1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-26 03:57:42 -05:00

VLESS PREVIEW 1.2

This commit is contained in:
RPRX 2020-08-03 06:13:26 +00:00 committed by GitHub
parent 2c49559c61
commit 1cfc02e720
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 335 additions and 70 deletions

View File

@ -17,12 +17,14 @@ type VLessInboundFallback struct {
Addr *Address `json:"addr"` Addr *Address `json:"addr"`
Port uint16 `json:"port"` Port uint16 `json:"port"`
Unix string `json:"unix"` Unix string `json:"unix"`
Xver uint16 `json:"xver"`
} }
type VLessInboundConfig struct { type VLessInboundConfig struct {
Users []json.RawMessage `json:"clients"` Users []json.RawMessage `json:"clients"`
Decryption string `json:"decryption"` Decryption string `json:"decryption"`
Fallback *VLessInboundFallback `json:"fallback"` Fallback *VLessInboundFallback `json:"fallback"`
Fallback_h2 *VLessInboundFallback `json:"fallback_h2"`
} }
// Build implements Buildable // Build implements Buildable
@ -36,6 +38,9 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
config.Decryption = c.Decryption config.Decryption = c.Decryption
if c.Fallback != nil { if c.Fallback != nil {
if c.Fallback.Xver > 2 {
return nil, newError(`VLESS "fallback": invalid PROXY protocol version, "xver" only accepts 0, 1, 2`)
}
if c.Fallback.Unix != "" { if c.Fallback.Unix != "" {
if c.Fallback.Unix[0] == '@' { if c.Fallback.Unix[0] == '@' {
c.Fallback.Unix = "\x00" + c.Fallback.Unix[1:] c.Fallback.Unix = "\x00" + c.Fallback.Unix[1:]
@ -54,6 +59,36 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
Addr: c.Fallback.Addr.Build(), Addr: c.Fallback.Addr.Build(),
Port: uint32(c.Fallback.Port), Port: uint32(c.Fallback.Port),
Unix: c.Fallback.Unix, Unix: c.Fallback.Unix,
Xver: uint32(c.Fallback.Xver),
}
}
if c.Fallback_h2 != nil {
if config.Fallback == nil {
return nil, newError(`VLESS "fallback_h2" can't exist alone without "fallback"`)
}
if c.Fallback_h2.Xver > 2 {
return nil, newError(`VLESS "fallback_h2": invalid PROXY protocol version, "xver" only accepts 0, 1, 2`)
}
if c.Fallback_h2.Unix != "" {
if c.Fallback_h2.Unix[0] == '@' {
c.Fallback_h2.Unix = "\x00" + c.Fallback_h2.Unix[1:]
}
} else {
if c.Fallback_h2.Port == 0 {
return nil, newError(`please fill in a valid value for "port" in VLESS "fallback_h2"`)
}
}
if c.Fallback_h2.Addr == nil {
c.Fallback_h2.Addr = &Address{
Address: net.ParseAddress("127.0.0.1"),
}
}
config.FallbackH2 = &inbound.FallbackH2{
Addr: c.Fallback_h2.Addr.Build(),
Port: uint32(c.Fallback_h2.Port),
Unix: c.Fallback_h2.Unix,
Xver: uint32(c.Fallback_h2.Xver),
} }
} }

View File

@ -79,7 +79,10 @@ func TestVLessInbound(t *testing.T) {
"decryption": "none", "decryption": "none",
"fallback": { "fallback": {
"port": 80, "port": 80,
"unix": "@/dev/shm/domain.socket" },
"fallback_h2": {
"unix": "@/dev/shm/domain.socket",
"xver": 2
} }
}`, }`,
Parser: loadJSON(creator), Parser: loadJSON(creator),
@ -102,7 +105,15 @@ func TestVLessInbound(t *testing.T) {
}, },
}, },
Port: 80, Port: 80,
},
FallbackH2: &inbound.FallbackH2{
Addr: &net.IPOrDomain{
Address: &net.IPOrDomain_Ip{
Ip: []byte{127, 0, 0, 1},
},
},
Unix: "\x00/dev/shm/domain.socket", Unix: "\x00/dev/shm/domain.socket",
Xver: 2,
}, },
}, },
}, },

View File

@ -17,7 +17,7 @@ func EncodeHeaderAddons(buffer *buf.Buffer, addons *Addons) error {
default: default:
if err := buffer.WriteByte(0); err != nil { if err := buffer.WriteByte(0); err != nil {
return newError("failed to write addons protobuf length").Base(err).AtWarning() return newError("failed to write addons protobuf length").Base(err)
} }
} }
@ -32,18 +32,18 @@ func DecodeHeaderAddons(buffer *buf.Buffer, reader io.Reader) (*Addons, error) {
buffer.Clear() buffer.Clear()
if _, err := buffer.ReadFullFrom(reader, 1); err != nil { if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
return nil, newError("failed to read addons protobuf length").Base(err).AtWarning() return nil, newError("failed to read addons protobuf length").Base(err)
} }
if length := int32(buffer.Byte(0)); length != 0 { if length := int32(buffer.Byte(0)); length != 0 {
buffer.Clear() buffer.Clear()
if _, err := buffer.ReadFullFrom(reader, length); err != nil { if _, err := buffer.ReadFullFrom(reader, length); err != nil {
return nil, newError("failed to read addons protobuf value").Base(err).AtWarning() return nil, newError("failed to read addons protobuf value").Base(err)
} }
if err := proto.Unmarshal(buffer.Bytes(), addons); err != nil { if err := proto.Unmarshal(buffer.Bytes(), addons); err != nil {
return nil, newError("failed to unmarshal addons protobuf value").Base(err).AtWarning() return nil, newError("failed to unmarshal addons protobuf value").Base(err)
} }
// Verification. // Verification.

View File

@ -29,29 +29,29 @@ func EncodeRequestHeader(writer io.Writer, request *protocol.RequestHeader, requ
defer buffer.Release() defer buffer.Release()
if err := buffer.WriteByte(request.Version); err != nil { if err := buffer.WriteByte(request.Version); err != nil {
return newError("failed to write request version").Base(err).AtWarning() return newError("failed to write request version").Base(err)
} }
if _, err := buffer.Write(request.User.Account.(*vless.MemoryAccount).ID.Bytes()); err != nil { if _, err := buffer.Write(request.User.Account.(*vless.MemoryAccount).ID.Bytes()); err != nil {
return newError("failed to write request user id").Base(err).AtWarning() return newError("failed to write request user id").Base(err)
} }
if err := EncodeHeaderAddons(&buffer, requestAddons); err != nil { if err := EncodeHeaderAddons(&buffer, requestAddons); err != nil {
return newError("failed to encode request header addons").Base(err).AtWarning() return newError("failed to encode request header addons").Base(err)
} }
if err := buffer.WriteByte(byte(request.Command)); err != nil { if err := buffer.WriteByte(byte(request.Command)); err != nil {
return newError("failed to write request command").Base(err).AtWarning() return newError("failed to write request command").Base(err)
} }
if request.Command != protocol.RequestCommandMux { if request.Command != protocol.RequestCommandMux {
if err := addrParser.WriteAddressPort(&buffer, request.Address, request.Port); err != nil { if err := addrParser.WriteAddressPort(&buffer, request.Address, request.Port); err != nil {
return newError("failed to write request address and port").Base(err).AtWarning() return newError("failed to write request address and port").Base(err)
} }
} }
if _, err := writer.Write(buffer.Bytes()); err != nil { if _, err := writer.Write(buffer.Bytes()); err != nil {
return newError("failed to write request header").Base(err).AtWarning() return newError("failed to write request header").Base(err)
} }
return nil return nil
@ -67,7 +67,7 @@ func DecodeRequestHeader(reader io.Reader, validator *vless.Validator) (*protoco
if _, err := buffer.ReadFullFrom(reader, 1); err != nil { if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
pre.Write(buffer.Bytes()) pre.Write(buffer.Bytes())
return nil, nil, newError("failed to read request version").Base(err).AtWarning(), pre return nil, nil, newError("failed to read request version").Base(err), pre
} }
request := &protocol.RequestHeader{ request := &protocol.RequestHeader{
@ -82,7 +82,7 @@ func DecodeRequestHeader(reader io.Reader, validator *vless.Validator) (*protoco
buffer.Clear() buffer.Clear()
if _, err := buffer.ReadFullFrom(reader, protocol.IDBytesLen); err != nil { if _, err := buffer.ReadFullFrom(reader, protocol.IDBytesLen); err != nil {
pre.Write(buffer.Bytes()) pre.Write(buffer.Bytes())
return nil, nil, newError("failed to read request user id").Base(err).AtWarning(), pre return nil, nil, newError("failed to read request user id").Base(err), pre
} }
var id [16]byte var id [16]byte
@ -90,17 +90,17 @@ func DecodeRequestHeader(reader io.Reader, validator *vless.Validator) (*protoco
if request.User = validator.Get(id); request.User == nil { if request.User = validator.Get(id); request.User == nil {
pre.Write(buffer.Bytes()) pre.Write(buffer.Bytes())
return nil, nil, newError("invalid request user id").AtWarning(), pre return nil, nil, newError("invalid request user id"), pre
} }
requestAddons, err := DecodeHeaderAddons(&buffer, reader) requestAddons, err := DecodeHeaderAddons(&buffer, reader)
if err != nil { if err != nil {
return nil, nil, newError("failed to decode request header addons").Base(err).AtWarning(), nil return nil, nil, newError("failed to decode request header addons").Base(err), nil
} }
buffer.Clear() buffer.Clear()
if _, err := buffer.ReadFullFrom(reader, 1); err != nil { if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
return nil, nil, newError("failed to read request command").Base(err).AtWarning(), nil return nil, nil, newError("failed to read request command").Base(err), nil
} }
request.Command = protocol.RequestCommand(buffer.Byte(0)) request.Command = protocol.RequestCommand(buffer.Byte(0))
@ -116,14 +116,14 @@ func DecodeRequestHeader(reader io.Reader, validator *vless.Validator) (*protoco
} }
if request.Address == nil { if request.Address == nil {
return nil, nil, newError("invalid request address").AtWarning(), nil return nil, nil, newError("invalid request address"), nil
} }
return request, requestAddons, nil, nil return request, requestAddons, nil, nil
default: default:
return nil, nil, newError("unexpected request version").AtWarning(), pre return nil, nil, newError("unexpected request version"), pre
} }
@ -136,15 +136,15 @@ func EncodeResponseHeader(writer io.Writer, request *protocol.RequestHeader, res
defer buffer.Release() defer buffer.Release()
if err := buffer.WriteByte(request.Version); err != nil { if err := buffer.WriteByte(request.Version); err != nil {
return newError("failed to write response version").Base(err).AtWarning() return newError("failed to write response version").Base(err)
} }
if err := EncodeHeaderAddons(&buffer, responseAddons); err != nil { if err := EncodeHeaderAddons(&buffer, responseAddons); err != nil {
return newError("failed to encode response header addons").Base(err).AtWarning() return newError("failed to encode response header addons").Base(err)
} }
if _, err := writer.Write(buffer.Bytes()); err != nil { if _, err := writer.Write(buffer.Bytes()); err != nil {
return newError("failed to write response header").Base(err).AtWarning() return newError("failed to write response header").Base(err)
} }
return nil return nil
@ -157,16 +157,16 @@ func DecodeResponseHeader(reader io.Reader, request *protocol.RequestHeader, res
defer buffer.Release() defer buffer.Release()
if _, err := buffer.ReadFullFrom(reader, 1); err != nil { if _, err := buffer.ReadFullFrom(reader, 1); err != nil {
return newError("failed to read response version").Base(err).AtWarning() return newError("failed to read response version").Base(err)
} }
if buffer.Byte(0) != request.Version { if buffer.Byte(0) != request.Version {
return newError("unexpected response version. Expecting ", int(request.Version), " but actually ", int(buffer.Byte(0))).AtWarning() return newError("unexpected response version. Expecting ", int(request.Version), " but actually ", int(buffer.Byte(0)))
} }
responseAddons, err := DecodeHeaderAddons(&buffer, reader) responseAddons, err := DecodeHeaderAddons(&buffer, reader)
if err != nil { if err != nil {
return newError("failed to decode response header addons").Base(err).AtWarning() return newError("failed to decode response header addons").Base(err)
} }
return nil return nil

View File

@ -35,6 +35,7 @@ type Fallback struct {
Addr *net.IPOrDomain `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` Addr *net.IPOrDomain `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
Port uint32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` Port uint32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"`
Unix string `protobuf:"bytes,3,opt,name=unix,proto3" json:"unix,omitempty"` Unix string `protobuf:"bytes,3,opt,name=unix,proto3" json:"unix,omitempty"`
Xver uint32 `protobuf:"varint,4,opt,name=xver,proto3" json:"xver,omitempty"`
} }
func (x *Fallback) Reset() { func (x *Fallback) Reset() {
@ -90,6 +91,84 @@ func (x *Fallback) GetUnix() string {
return "" return ""
} }
func (x *Fallback) GetXver() uint32 {
if x != nil {
return x.Xver
}
return 0
}
type FallbackH2 struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Addr *net.IPOrDomain `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
Port uint32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"`
Unix string `protobuf:"bytes,3,opt,name=unix,proto3" json:"unix,omitempty"`
Xver uint32 `protobuf:"varint,4,opt,name=xver,proto3" json:"xver,omitempty"`
}
func (x *FallbackH2) Reset() {
*x = FallbackH2{}
if protoimpl.UnsafeEnabled {
mi := &file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *FallbackH2) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*FallbackH2) ProtoMessage() {}
func (x *FallbackH2) ProtoReflect() protoreflect.Message {
mi := &file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes[1]
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 FallbackH2.ProtoReflect.Descriptor instead.
func (*FallbackH2) Descriptor() ([]byte, []int) {
return file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDescGZIP(), []int{1}
}
func (x *FallbackH2) GetAddr() *net.IPOrDomain {
if x != nil {
return x.Addr
}
return nil
}
func (x *FallbackH2) GetPort() uint32 {
if x != nil {
return x.Port
}
return 0
}
func (x *FallbackH2) GetUnix() string {
if x != nil {
return x.Unix
}
return ""
}
func (x *FallbackH2) GetXver() uint32 {
if x != nil {
return x.Xver
}
return 0
}
type Config struct { type Config struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -97,14 +176,15 @@ type Config struct {
User []*protocol.User `protobuf:"bytes,1,rep,name=user,proto3" json:"user,omitempty"` User []*protocol.User `protobuf:"bytes,1,rep,name=user,proto3" json:"user,omitempty"`
// Decryption settings. Only applies to server side, and only accepts "none" for now. // Decryption settings. Only applies to server side, and only accepts "none" for now.
Decryption string `protobuf:"bytes,2,opt,name=decryption,proto3" json:"decryption,omitempty"` Decryption string `protobuf:"bytes,2,opt,name=decryption,proto3" json:"decryption,omitempty"`
Fallback *Fallback `protobuf:"bytes,3,opt,name=fallback,proto3" json:"fallback,omitempty"` Fallback *Fallback `protobuf:"bytes,3,opt,name=fallback,proto3" json:"fallback,omitempty"`
FallbackH2 *FallbackH2 `protobuf:"bytes,4,opt,name=fallback_h2,json=fallbackH2,proto3" json:"fallback_h2,omitempty"`
} }
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes[1] mi := &file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -117,7 +197,7 @@ func (x *Config) String() string {
func (*Config) ProtoMessage() {} func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes[1] mi := &file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -130,7 +210,7 @@ func (x *Config) ProtoReflect() protoreflect.Message {
// Deprecated: Use Config.ProtoReflect.Descriptor instead. // Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) { func (*Config) Descriptor() ([]byte, []int) {
return file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDescGZIP(), []int{1} return file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDescGZIP(), []int{2}
} }
func (x *Config) GetUser() []*protocol.User { func (x *Config) GetUser() []*protocol.User {
@ -154,6 +234,13 @@ func (x *Config) GetFallback() *Fallback {
return nil return nil
} }
func (x *Config) GetFallbackH2() *FallbackH2 {
if x != nil {
return x.FallbackH2
}
return nil
}
var File_v2ray_com_core_proxy_vless_inbound_config_proto protoreflect.FileDescriptor var File_v2ray_com_core_proxy_vless_inbound_config_proto protoreflect.FileDescriptor
var file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDesc = []byte{ var file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDesc = []byte{
@ -167,30 +254,44 @@ var file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDesc = []byte{
0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x76, 0x32, 0x72, 0x61, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x76, 0x32, 0x72, 0x61,
0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x69, 0x0a, 0x08, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7d, 0x0a, 0x08, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
0x6b, 0x12, 0x35, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x6b, 0x12, 0x35, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61,
0x69, 0x6e, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04,
0x75, 0x6e, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x78, 0x75, 0x6e, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x78,
0x22, 0xa4, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x04, 0x75, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x76, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04,
0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x78, 0x76, 0x65, 0x72, 0x22, 0x80, 0x01, 0x0a, 0x0b, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6b, 0x5f, 0x68, 0x32, 0x12, 0x35, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01,
0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x70,
0x6e, 0x12, 0x44, 0x0a, 0x08, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12,
0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75,
0x6e, 0x69, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x76, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x04, 0x78, 0x76, 0x65, 0x72, 0x22, 0xf2, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x34, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, 0x73,
0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x63, 0x72,
0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65,
0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x66, 0x61, 0x6c, 0x6c,
0x62, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x76, 0x32, 0x72,
0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c,
0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x46, 0x61, 0x6c, 0x6c,
0x62, 0x61, 0x63, 0x6b, 0x52, 0x08, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x4c,
0x0a, 0x0b, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x68, 0x32, 0x18, 0x04, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62,
0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x08, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x68, 0x32,
0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x42, 0x50, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x52, 0x0a, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x48, 0x32, 0x42, 0x50, 0x0a, 0x22,
0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70,
0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75,
0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1e, 0x56, 0x32, 0x52, 0x61, 0x79, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1e,
0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6c, 0x65, 0x73, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79,
0x73, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06,
0x33, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -205,22 +306,25 @@ func file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDescGZIP() []byte {
return file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDescData return file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDescData
} }
var file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_v2ray_com_core_proxy_vless_inbound_config_proto_goTypes = []interface{}{ var file_v2ray_com_core_proxy_vless_inbound_config_proto_goTypes = []interface{}{
(*Fallback)(nil), // 0: v2ray.core.proxy.vless.inbound.Fallback (*Fallback)(nil), // 0: v2ray.core.proxy.vless.inbound.Fallback
(*Config)(nil), // 1: v2ray.core.proxy.vless.inbound.Config (*FallbackH2)(nil), // 1: v2ray.core.proxy.vless.inbound.Fallback_h2
(*net.IPOrDomain)(nil), // 2: v2ray.core.common.net.IPOrDomain (*Config)(nil), // 2: v2ray.core.proxy.vless.inbound.Config
(*protocol.User)(nil), // 3: v2ray.core.common.protocol.User (*net.IPOrDomain)(nil), // 3: v2ray.core.common.net.IPOrDomain
(*protocol.User)(nil), // 4: v2ray.core.common.protocol.User
} }
var file_v2ray_com_core_proxy_vless_inbound_config_proto_depIdxs = []int32{ var file_v2ray_com_core_proxy_vless_inbound_config_proto_depIdxs = []int32{
2, // 0: v2ray.core.proxy.vless.inbound.Fallback.addr:type_name -> v2ray.core.common.net.IPOrDomain 3, // 0: v2ray.core.proxy.vless.inbound.Fallback.addr:type_name -> v2ray.core.common.net.IPOrDomain
3, // 1: v2ray.core.proxy.vless.inbound.Config.user:type_name -> v2ray.core.common.protocol.User 3, // 1: v2ray.core.proxy.vless.inbound.Fallback_h2.addr:type_name -> v2ray.core.common.net.IPOrDomain
0, // 2: v2ray.core.proxy.vless.inbound.Config.fallback:type_name -> v2ray.core.proxy.vless.inbound.Fallback 4, // 2: v2ray.core.proxy.vless.inbound.Config.user:type_name -> v2ray.core.common.protocol.User
3, // [3:3] is the sub-list for method output_type 0, // 3: v2ray.core.proxy.vless.inbound.Config.fallback:type_name -> v2ray.core.proxy.vless.inbound.Fallback
3, // [3:3] is the sub-list for method input_type 1, // 4: v2ray.core.proxy.vless.inbound.Config.fallback_h2:type_name -> v2ray.core.proxy.vless.inbound.Fallback_h2
3, // [3:3] is the sub-list for extension type_name 5, // [5:5] is the sub-list for method output_type
3, // [3:3] is the sub-list for extension extendee 5, // [5:5] is the sub-list for method input_type
0, // [0:3] is the sub-list for field type_name 5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
} }
func init() { file_v2ray_com_core_proxy_vless_inbound_config_proto_init() } func init() { file_v2ray_com_core_proxy_vless_inbound_config_proto_init() }
@ -242,6 +346,18 @@ func file_v2ray_com_core_proxy_vless_inbound_config_proto_init() {
} }
} }
file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*FallbackH2); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_v2ray_com_core_proxy_vless_inbound_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Config); i { switch v := v.(*Config); i {
case 0: case 0:
return &v.state return &v.state
@ -260,7 +376,7 @@ func file_v2ray_com_core_proxy_vless_inbound_config_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDesc, RawDescriptor: file_v2ray_com_core_proxy_vless_inbound_config_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 2, NumMessages: 3,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

View File

@ -13,6 +13,14 @@ message Fallback {
v2ray.core.common.net.IPOrDomain addr = 1; v2ray.core.common.net.IPOrDomain addr = 1;
uint32 port = 2; uint32 port = 2;
string unix = 3; string unix = 3;
uint32 xver = 4;
}
message Fallback_h2 {
v2ray.core.common.net.IPOrDomain addr = 1;
uint32 port = 2;
string unix = 3;
uint32 xver = 4;
} }
message Config { message Config {
@ -20,4 +28,5 @@ message Config {
// Decryption settings. Only applies to server side, and only accepts "none" for now. // Decryption settings. Only applies to server side, and only accepts "none" for now.
string decryption = 2; string decryption = 2;
Fallback fallback = 3; Fallback fallback = 3;
Fallback_h2 fallback_h2 = 4;
} }

View File

@ -6,6 +6,7 @@ package inbound
import ( import (
"context" "context"
"encoding/hex"
"io" "io"
"strconv" "strconv"
"time" "time"
@ -28,6 +29,7 @@ import (
"v2ray.com/core/proxy/vless" "v2ray.com/core/proxy/vless"
"v2ray.com/core/proxy/vless/encoding" "v2ray.com/core/proxy/vless/encoding"
"v2ray.com/core/transport/internet" "v2ray.com/core/transport/internet"
"v2ray.com/core/transport/internet/tls"
) )
func init() { func init() {
@ -51,6 +53,8 @@ type Handler struct {
dns dns.Client dns dns.Client
fallback *Fallback // or nil fallback *Fallback // or nil
addrport string addrport string
fallback_h2 *FallbackH2 // or nil
addrport_h2 string
} }
// New creates a new VLess inbound handler. // New creates a new VLess inbound handler.
@ -78,6 +82,10 @@ func New(ctx context.Context, config *Config, dc dns.Client) (*Handler, error) {
handler.fallback = config.Fallback handler.fallback = config.Fallback
handler.addrport = handler.fallback.Addr.AsAddress().String() + ":" + strconv.Itoa(int(handler.fallback.Port)) handler.addrport = handler.fallback.Addr.AsAddress().String() + ":" + strconv.Itoa(int(handler.fallback.Port))
} }
if config.FallbackH2 != nil {
handler.fallback_h2 = config.FallbackH2
handler.addrport_h2 = handler.fallback_h2.Addr.AsAddress().String() + ":" + strconv.Itoa(int(handler.fallback_h2.Port))
}
return handler, nil return handler, nil
} }
@ -113,6 +121,33 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
first := buf.New() first := buf.New()
first.ReadFrom(connection) first.ReadFrom(connection)
var fallback uint32
var addrport string
var unixpath string
var proxyver uint32
if h.fallback != nil {
fallback = 1
addrport = h.addrport
unixpath = h.fallback.Unix
proxyver = h.fallback.Xver
}
if h.fallback_h2 != nil {
iConn := connection
if statConn, ok := iConn.(*internet.StatCouterConnection); ok {
iConn = statConn.Connection
}
if tlsConn, ok := iConn.(*tls.Conn); ok {
if tlsConn.ConnectionState().NegotiatedProtocol == "h2" {
fallback = 2
addrport = h.addrport_h2
unixpath = h.fallback_h2.Unix
proxyver = h.fallback_h2.Xver
}
}
}
sid := session.ExportIDToError(ctx) sid := session.ExportIDToError(ctx)
newError("firstLen = ", first.Len()).AtInfo().WriteToLog(sid) newError("firstLen = ", first.Len()).AtInfo().WriteToLog(sid)
@ -126,26 +161,33 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
var err error var err error
var pre *buf.Buffer var pre *buf.Buffer
if h.fallback != nil && first.Len() < 18 { if fallback > 0 && first.Len() < 18 {
err = newError("fallback directly") err = newError("fallback directly")
pre = buf.New()
} else { } else {
request, requestAddons, err, pre = encoding.DecodeRequestHeader(reader, h.validator) request, requestAddons, err, pre = encoding.DecodeRequestHeader(reader, h.validator)
if pre == nil {
fallback = 0
}
} }
if err != nil { if err != nil {
if h.fallback != nil && pre != nil { if fallback > 0 {
newError("fallback starts").AtInfo().WriteToLog(sid) switch fallback {
case 1:
newError("fallback starts").Base(err).AtInfo().WriteToLog(sid)
case 2:
newError("fallback_h2 starts").Base(err).AtInfo().WriteToLog(sid)
}
var conn net.Conn var conn net.Conn
if err := retry.ExponentialBackoff(5, 100).On(func() error { if err := retry.ExponentialBackoff(5, 100).On(func() error {
var dialer net.Dialer var dialer net.Dialer
var err error var err error
if h.fallback.Unix != "" { if unixpath != "" {
conn, err = dialer.DialContext(ctx, "unix", h.fallback.Unix) conn, err = dialer.DialContext(ctx, "unix", unixpath)
} else { } else {
conn, err = dialer.DialContext(ctx, "tcp", h.addrport) conn, err = dialer.DialContext(ctx, "tcp", addrport)
} }
if err != nil { if err != nil {
return err return err
@ -166,7 +208,59 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
postRequest := func() error { postRequest := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
if pre.Len() > 0 { if proxyver > 0 {
remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String())
if err != nil {
return err
}
localAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String())
if err != nil {
return err
}
ipv4 := true
for i := 0; i < len(remoteAddr); i++ {
if remoteAddr[i] == ':' {
ipv4 = false
break
}
}
pro := buf.New()
switch proxyver {
case 1:
if ipv4 {
pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))
} else {
pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))
}
case 2:
pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21")) // signature + v2 + PROXY
if ipv4 {
pro.Write([]byte("\x11\x00\x0C")) // AF_INET + STREAM + 12 bytes
pro.Write(net.ParseIP(remoteAddr).To4())
pro.Write(net.ParseIP(localAddr).To4())
} else {
pro.Write([]byte("\x21\x00\x24")) // AF_INET6 + STREAM + 36 bytes
pro.Write(net.ParseIP(remoteAddr).To16())
pro.Write(net.ParseIP(localAddr).To16())
}
p1, _ := strconv.ParseInt(remotePort, 10, 64)
b1, _ := hex.DecodeString(strconv.FormatInt(p1, 16))
p2, _ := strconv.ParseInt(localPort, 10, 64)
b2, _ := hex.DecodeString(strconv.FormatInt(p2, 16))
if len(b1) == 1 {
pro.WriteByte(0)
}
pro.Write(b1)
if len(b2) == 1 {
pro.WriteByte(0)
}
pro.Write(b2)
}
if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil {
return newError("failed to set PROXY protocol v", proxyver).Base(err).AtWarning()
}
}
if pre != nil && pre.Len() > 0 {
if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pre}); err != nil { if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pre}); err != nil {
return newError("failed to fallback request pre").Base(err).AtWarning() return newError("failed to fallback request pre").Base(err).AtWarning()
} }