1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-29 02:35:23 +00:00

VLESS PREVIEW 1.5

This commit is contained in:
RPRX 2020-08-28 07:51:09 +00:00 committed by GitHub
parent 3ad73fde20
commit 84aaf3a1e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 374 additions and 406 deletions

View File

@ -2,6 +2,7 @@ package conf
import ( import (
"encoding/json" "encoding/json"
"strconv"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
@ -14,17 +15,18 @@ import (
) )
type VLessInboundFallback struct { type VLessInboundFallback struct {
Addr *Address `json:"addr"` Alpn string `json:"alpn"`
Port uint16 `json:"port"` Path string `json:"path"`
Unix string `json:"unix"` Type string `json:"type"`
Xver uint16 `json:"xver"` Dest json.RawMessage `json:"dest"`
Xver uint64 `json:"xver"`
} }
type VLessInboundConfig struct { type VLessInboundConfig struct {
Users []json.RawMessage `json:"clients"` Clients []json.RawMessage `json:"clients"`
Decryption string `json:"decryption"` Decryption string `json:"decryption"`
Fallback *VLessInboundFallback `json:"fallback"` Fallback json.RawMessage `json:"fallback"`
Fallback_h2 *VLessInboundFallback `json:"fallback_h2"` Fallbacks []*VLessInboundFallback `json:"fallbacks"`
} }
// Build implements Buildable // Build implements Buildable
@ -32,99 +34,103 @@ func (c *VLessInboundConfig) Build() (proto.Message, error) {
config := new(inbound.Config) config := new(inbound.Config)
if len(c.Clients) == 0 {
return nil, newError(`VLESS settings: "clients" is empty`)
}
config.Clients = make([]*protocol.User, len(c.Clients))
for idx, rawUser := range c.Clients {
user := new(protocol.User)
if err := json.Unmarshal(rawUser, user); err != nil {
return nil, newError(`VLESS clients: invalid user`).Base(err)
}
account := new(vless.Account)
if err := json.Unmarshal(rawUser, account); err != nil {
return nil, newError(`VLESS clients: invalid user`).Base(err)
}
if account.Schedulers != "" {
return nil, newError(`VLESS clients: "schedulers" is not available in this version`)
}
if account.Encryption != "" {
return nil, newError(`VLESS clients: "encryption" should not in inbound settings`)
}
user.Account = serial.ToTypedMessage(account)
config.Clients[idx] = user
}
if c.Decryption != "none" { if c.Decryption != "none" {
return nil, newError(`please add/set "decryption":"none" directly to every VLESS "settings"`) return nil, newError(`VLESS settings: please add/set "decryption":"none" to every settings`)
} }
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 settings: please use "fallbacks":[{}] instead of "fallback":{}`)
return nil, newError(`VLESS "fallback": invalid PROXY protocol version, "xver" only accepts 0, 1, 2`)
}
if c.Fallback.Unix != "" {
if c.Fallback.Unix[0] == '@' {
c.Fallback.Unix = "\x00" + c.Fallback.Unix[1:]
}
} else {
if c.Fallback.Port == 0 {
return nil, newError(`please fill in a valid value for "port" in VLESS "fallback"`)
}
}
if c.Fallback.Addr == nil {
c.Fallback.Addr = &Address{
Address: net.ParseAddress("127.0.0.1"),
}
}
config.Fallback = &inbound.Fallback{
Addr: c.Fallback.Addr.Build(),
Port: uint32(c.Fallback.Port),
Unix: c.Fallback.Unix,
Xver: uint32(c.Fallback.Xver),
}
} }
for _, fb := range c.Fallbacks {
if c.Fallback_h2 != nil { var i uint16
if config.Fallback == nil { var s string
return nil, newError(`VLESS "fallback_h2" can't exist alone without "fallback"`) if err := json.Unmarshal(fb.Dest, &i); err == nil {
} s = strconv.Itoa(int(i))
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 { } else {
if c.Fallback_h2.Port == 0 { _ = json.Unmarshal(fb.Dest, &s)
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),
} }
config.Fallbacks = append(config.Fallbacks, &inbound.Fallback{
Alpn: fb.Alpn,
Path: fb.Path,
Type: fb.Type,
Dest: s,
Xver: fb.Xver,
})
} }
for _, fb := range config.Fallbacks {
config.User = make([]*protocol.User, len(c.Users)) /*
for idx, rawData := range c.Users { if fb.Alpn == "h2" && fb.Path != "" {
user := new(protocol.User) return nil, newError(`VLESS fallbacks: "alpn":"h2" doesn't support "path"`)
if err := json.Unmarshal(rawData, user); err != nil { }
return nil, newError("invalid VLESS user").Base(err) */
if fb.Path != "" && fb.Path[0] != '/' {
return nil, newError(`VLESS fallbacks: "path" must be empty or start with "/"`)
} }
account := new(vless.Account) if fb.Type == "" && fb.Dest != "" {
if err := json.Unmarshal(rawData, account); err != nil { if fb.Dest == "serve-ws-none" {
return nil, newError("invalid VLESS user").Base(err) fb.Type = "serve"
} else {
switch fb.Dest[0] {
case '@':
fb.Dest = "\x00" + fb.Dest[1:]
fallthrough
case '/':
fb.Type = "unix"
default:
if _, err := strconv.Atoi(fb.Dest); err == nil {
fb.Dest = "127.0.0.1:" + fb.Dest
}
if _, _, err := net.SplitHostPort(fb.Dest); err == nil {
fb.Type = "tcp"
}
}
}
} }
if fb.Type == "" {
if account.Schedulers != "" { return nil, newError(`VLESS fallbacks: please fill in a valid value for every "dest"`)
return nil, newError(`VLESS attr "schedulers" is not available in this version`)
} }
if account.Encryption != "" { if fb.Xver > 2 {
return nil, newError(`VLESS attr "encryption" should not in inbound settings`) return nil, newError(`VLESS fallbacks: invalid PROXY protocol version, "xver" only accepts 0, 1, 2`)
} }
user.Account = serial.ToTypedMessage(account)
config.User[idx] = user
} }
return config, nil return config, nil
} }
type VLessOutboundTarget struct { type VLessOutboundVnext struct {
Address *Address `json:"address"` Address *Address `json:"address"`
Port uint16 `json:"port"` Port uint16 `json:"port"`
Users []json.RawMessage `json:"users"` Users []json.RawMessage `json:"users"`
} }
type VLessOutboundConfig struct { type VLessOutboundConfig struct {
Receivers []*VLessOutboundTarget `json:"vnext"` Vnext []*VLessOutboundVnext `json:"vnext"`
} }
// Build implements Buildable // Build implements Buildable
@ -132,44 +138,44 @@ func (c *VLessOutboundConfig) Build() (proto.Message, error) {
config := new(outbound.Config) config := new(outbound.Config)
if len(c.Receivers) == 0 { if len(c.Vnext) == 0 {
return nil, newError("0 VLESS receiver configured") return nil, newError(`VLESS settings: "vnext" is empty`)
} }
serverSpecs := make([]*protocol.ServerEndpoint, len(c.Receivers)) config.Vnext = make([]*protocol.ServerEndpoint, len(c.Vnext))
for idx, rec := range c.Receivers { for idx, rec := range c.Vnext {
if len(rec.Users) == 0 {
return nil, newError("0 user configured for VLESS outbound")
}
if rec.Address == nil { if rec.Address == nil {
return nil, newError("address is not set in VLESS outbound config") return nil, newError(`VLESS vnext: "address" is not set`)
}
if len(rec.Users) == 0 {
return nil, newError(`VLESS vnext: "users" is empty`)
} }
spec := &protocol.ServerEndpoint{ spec := &protocol.ServerEndpoint{
Address: rec.Address.Build(), Address: rec.Address.Build(),
Port: uint32(rec.Port), Port: uint32(rec.Port),
User: make([]*protocol.User, len(rec.Users)),
} }
for _, rawUser := range rec.Users { for idx, rawUser := range rec.Users {
user := new(protocol.User) user := new(protocol.User)
if err := json.Unmarshal(rawUser, user); err != nil { if err := json.Unmarshal(rawUser, user); err != nil {
return nil, newError("invalid VLESS user").Base(err) return nil, newError(`VLESS users: invalid user`).Base(err)
} }
account := new(vless.Account) account := new(vless.Account)
if err := json.Unmarshal(rawUser, account); err != nil { if err := json.Unmarshal(rawUser, account); err != nil {
return nil, newError("invalid VLESS user").Base(err) return nil, newError(`VLESS users: invalid user`).Base(err)
} }
if account.Schedulers != "" { if account.Schedulers != "" {
return nil, newError(`VLESS attr "schedulers" is not available in this version`) return nil, newError(`VLESS users: "schedulers" is not available in this version`)
} }
if account.Encryption != "none" { if account.Encryption != "none" {
return nil, newError(`please add/set "encryption":"none" for every VLESS user in "users"`) return nil, newError(`VLESS users: please add/set "encryption":"none" for every user`)
} }
user.Account = serial.ToTypedMessage(account) user.Account = serial.ToTypedMessage(account)
spec.User = append(spec.User, user) spec.User[idx] = user
} }
serverSpecs[idx] = spec config.Vnext[idx] = spec
} }
config.Receiver = serverSpecs
return config, nil return config, nil
} }

View File

@ -26,7 +26,6 @@ func TestVLessOutbound(t *testing.T) {
"users": [ "users": [
{ {
"id": "27848739-7e62-4138-9fd3-098a63964b6b", "id": "27848739-7e62-4138-9fd3-098a63964b6b",
"schedulers": "",
"encryption": "none", "encryption": "none",
"level": 0 "level": 0
} }
@ -35,7 +34,7 @@ func TestVLessOutbound(t *testing.T) {
}`, }`,
Parser: loadJSON(creator), Parser: loadJSON(creator),
Output: &outbound.Config{ Output: &outbound.Config{
Receiver: []*protocol.ServerEndpoint{ Vnext: []*protocol.ServerEndpoint{
{ {
Address: &net.IPOrDomain{ Address: &net.IPOrDomain{
Address: &net.IPOrDomain_Domain{ Address: &net.IPOrDomain_Domain{
@ -47,7 +46,6 @@ func TestVLessOutbound(t *testing.T) {
{ {
Account: serial.ToTypedMessage(&vless.Account{ Account: serial.ToTypedMessage(&vless.Account{
Id: "27848739-7e62-4138-9fd3-098a63964b6b", Id: "27848739-7e62-4138-9fd3-098a63964b6b",
Schedulers: "",
Encryption: "none", Encryption: "none",
}), }),
Level: 0, Level: 0,
@ -71,49 +69,60 @@ func TestVLessInbound(t *testing.T) {
"clients": [ "clients": [
{ {
"id": "27848739-7e62-4138-9fd3-098a63964b6b", "id": "27848739-7e62-4138-9fd3-098a63964b6b",
"schedulers": "",
"level": 0, "level": 0,
"email": "love@v2fly.org" "email": "love@v2fly.org"
} }
], ],
"decryption": "none", "decryption": "none",
"fallback": { "fallbacks": [
"port": 80 {
}, "dest": 80
"fallback_h2": { },
"unix": "@/dev/shm/domain.socket", {
"xver": 2 "alpn": "h2",
} "dest": "@/dev/shm/domain.socket",
"xver": 2
},
{
"path": "/innerws",
"dest": "serve-ws-none"
}
]
}`, }`,
Parser: loadJSON(creator), Parser: loadJSON(creator),
Output: &inbound.Config{ Output: &inbound.Config{
User: []*protocol.User{ Clients: []*protocol.User{
{ {
Account: serial.ToTypedMessage(&vless.Account{ Account: serial.ToTypedMessage(&vless.Account{
Id: "27848739-7e62-4138-9fd3-098a63964b6b", Id: "27848739-7e62-4138-9fd3-098a63964b6b",
Schedulers: "",
}), }),
Level: 0, Level: 0,
Email: "love@v2fly.org", Email: "love@v2fly.org",
}, },
}, },
Decryption: "none", Decryption: "none",
Fallback: &inbound.Fallback{ Fallbacks: []*inbound.Fallback{
Addr: &net.IPOrDomain{ {
Address: &net.IPOrDomain_Ip{ Alpn: "",
Ip: []byte{127, 0, 0, 1}, Path: "",
}, Type: "tcp",
Dest: "127.0.0.1:80",
Xver: 0,
}, },
Port: 80, {
}, Alpn: "h2",
FallbackH2: &inbound.FallbackH2{ Path: "",
Addr: &net.IPOrDomain{ Type: "unix",
Address: &net.IPOrDomain_Ip{ Dest: "\x00/dev/shm/domain.socket",
Ip: []byte{127, 0, 0, 1}, Xver: 2,
}, },
{
Alpn: "",
Path: "/innerws",
Type: "serve",
Dest: "serve-ws-none",
Xver: 0,
}, },
Unix: "\x00/dev/shm/domain.socket",
Xver: 2,
}, },
}, },
}, },

View File

@ -1,5 +1,9 @@
// +build !confonly
package encoding package encoding
//go:generate errorgen
import ( import (
"io" "io"
@ -9,8 +13,6 @@ import (
"v2ray.com/core/proxy/vless" "v2ray.com/core/proxy/vless"
) )
//go:generate errorgen
const ( const (
Version = byte(0) Version = byte(0)
) )

View File

@ -12,7 +12,6 @@ import (
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect" reflect "reflect"
sync "sync" sync "sync"
net "v2ray.com/core/common/net"
protocol "v2ray.com/core/common/protocol" protocol "v2ray.com/core/common/protocol"
) )
@ -32,10 +31,11 @@ type Fallback struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Addr *net.IPOrDomain `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` Alpn string `protobuf:"bytes,1,opt,name=alpn,proto3" json:"alpn,omitempty"`
Port uint32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
Unix string `protobuf:"bytes,3,opt,name=unix,proto3" json:"unix,omitempty"` Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"`
Xver uint32 `protobuf:"varint,4,opt,name=xver,proto3" json:"xver,omitempty"` Dest string `protobuf:"bytes,4,opt,name=dest,proto3" json:"dest,omitempty"`
Xver uint64 `protobuf:"varint,5,opt,name=xver,proto3" json:"xver,omitempty"`
} }
func (x *Fallback) Reset() { func (x *Fallback) Reset() {
@ -70,99 +70,35 @@ func (*Fallback) Descriptor() ([]byte, []int) {
return file_proxy_vless_inbound_config_proto_rawDescGZIP(), []int{0} return file_proxy_vless_inbound_config_proto_rawDescGZIP(), []int{0}
} }
func (x *Fallback) GetAddr() *net.IPOrDomain { func (x *Fallback) GetAlpn() string {
if x != nil { if x != nil {
return x.Addr return x.Alpn
}
return nil
}
func (x *Fallback) GetPort() uint32 {
if x != nil {
return x.Port
}
return 0
}
func (x *Fallback) GetUnix() string {
if x != nil {
return x.Unix
} }
return "" return ""
} }
func (x *Fallback) GetXver() uint32 { func (x *Fallback) GetPath() string {
if x != nil { if x != nil {
return x.Xver return x.Path
}
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_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_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_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 "" return ""
} }
func (x *FallbackH2) GetXver() uint32 { func (x *Fallback) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Fallback) GetDest() string {
if x != nil {
return x.Dest
}
return ""
}
func (x *Fallback) GetXver() uint64 {
if x != nil { if x != nil {
return x.Xver return x.Xver
} }
@ -174,17 +110,16 @@ type Config struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
User []*protocol.User `protobuf:"bytes,1,rep,name=user,proto3" json:"user,omitempty"` Clients []*protocol.User `protobuf:"bytes,1,rep,name=clients,proto3" json:"clients,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"` Fallbacks []*Fallback `protobuf:"bytes,3,rep,name=fallbacks,proto3" json:"fallbacks,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_proxy_vless_inbound_config_proto_msgTypes[2] mi := &file_proxy_vless_inbound_config_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -197,7 +132,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_proxy_vless_inbound_config_proto_msgTypes[2] mi := &file_proxy_vless_inbound_config_proto_msgTypes[1]
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 {
@ -210,12 +145,12 @@ 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_proxy_vless_inbound_config_proto_rawDescGZIP(), []int{2} return file_proxy_vless_inbound_config_proto_rawDescGZIP(), []int{1}
} }
func (x *Config) GetUser() []*protocol.User { func (x *Config) GetClients() []*protocol.User {
if x != nil { if x != nil {
return x.User return x.Clients
} }
return nil return nil
} }
@ -227,16 +162,9 @@ func (x *Config) GetDecryption() string {
return "" return ""
} }
func (x *Config) GetFallback() *Fallback { func (x *Config) GetFallbacks() []*Fallback {
if x != nil { if x != nil {
return x.Fallback return x.Fallbacks
}
return nil
}
func (x *Config) GetFallbackH2() *FallbackH2 {
if x != nil {
return x.FallbackH2
} }
return nil return nil
} }
@ -248,49 +176,34 @@ var file_proxy_vless_inbound_config_proto_rawDesc = []byte{
0x62, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x1e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x74, 0x6f, 0x12, 0x1e, 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, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75,
0x6e, 0x64, 0x1a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x61, 0x6e, 0x64, 0x1a, 0x1a, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x63, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6e,
0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x75, 0x73, 0x0a, 0x08, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x6c,
0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7d, 0x0a, 0x08, 0x46, 0x61, 0x6c, 0x6c, 0x70, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x6c, 0x70, 0x6e, 0x12, 0x12,
0x62, 0x61, 0x63, 0x6b, 0x12, 0x35, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61,
0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x74, 0x18, 0x04,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x76,
0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x78, 0x76, 0x65, 0x72, 0x22, 0xac,
0x12, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3a, 0x0a, 0x07, 0x63, 0x6c, 0x69,
0x6e, 0x69, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x76, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72,
0x0d, 0x52, 0x04, 0x78, 0x76, 0x65, 0x72, 0x22, 0x80, 0x01, 0x0a, 0x0b, 0x46, 0x61, 0x6c, 0x6c, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70,
0x62, 0x61, 0x63, 0x6b, 0x5f, 0x68, 0x32, 0x12, 0x35, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x07, 0x63, 0x6c,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74,
0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x63, 0x72, 0x79,
0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x12, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x0a, 0x09, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79,
0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73,
0x52, 0x04, 0x75, 0x6e, 0x69, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x76, 0x65, 0x72, 0x18, 0x04, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x78, 0x76, 0x65, 0x72, 0x22, 0xf2, 0x01, 0x0a, 0x06, 0x43, 0x63, 0x6b, 0x52, 0x09, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x42, 0x6b, 0x0a,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x62, 0x6f,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x22, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6c, 0x65, 0x73,
0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x73, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1e, 0x56, 0x32, 0x52, 0x61,
0x0a, 0x64, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x66, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6c, 0x65,
0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x73, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6f, 0x33,
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, 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,
0x5f, 0x68, 0x32, 0x52, 0x0a, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x48, 0x32, 0x42,
0x6b, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 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, 0x50, 0x01, 0x5a, 0x22, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6c,
0x65, 0x73, 0x73, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1e, 0x56, 0x32,
0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56,
0x6c, 0x65, 0x73, 0x73, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -305,25 +218,20 @@ func file_proxy_vless_inbound_config_proto_rawDescGZIP() []byte {
return file_proxy_vless_inbound_config_proto_rawDescData return file_proxy_vless_inbound_config_proto_rawDescData
} }
var file_proxy_vless_inbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_proxy_vless_inbound_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_proxy_vless_inbound_config_proto_goTypes = []interface{}{ var file_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
(*FallbackH2)(nil), // 1: v2ray.core.proxy.vless.inbound.Fallback_h2 (*Config)(nil), // 1: v2ray.core.proxy.vless.inbound.Config
(*Config)(nil), // 2: v2ray.core.proxy.vless.inbound.Config (*protocol.User)(nil), // 2: 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_proxy_vless_inbound_config_proto_depIdxs = []int32{ var file_proxy_vless_inbound_config_proto_depIdxs = []int32{
3, // 0: v2ray.core.proxy.vless.inbound.Fallback.addr:type_name -> v2ray.core.common.net.IPOrDomain 2, // 0: v2ray.core.proxy.vless.inbound.Config.clients: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, // 1: v2ray.core.proxy.vless.inbound.Config.fallbacks:type_name -> v2ray.core.proxy.vless.inbound.Fallback
4, // 2: v2ray.core.proxy.vless.inbound.Config.user:type_name -> v2ray.core.common.protocol.User 2, // [2:2] 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 2, // [2:2] 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 2, // [2:2] is the sub-list for extension type_name
5, // [5:5] is the sub-list for method output_type 2, // [2:2] is the sub-list for extension extendee
5, // [5:5] is the sub-list for method input_type 0, // [0:2] 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_proxy_vless_inbound_config_proto_init() } func init() { file_proxy_vless_inbound_config_proto_init() }
@ -345,18 +253,6 @@ func file_proxy_vless_inbound_config_proto_init() {
} }
} }
file_proxy_vless_inbound_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { file_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_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
@ -375,7 +271,7 @@ func file_proxy_vless_inbound_config_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proxy_vless_inbound_config_proto_rawDesc, RawDescriptor: file_proxy_vless_inbound_config_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 3, NumMessages: 2,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

View File

@ -6,27 +6,19 @@ option go_package = "v2ray.com/core/proxy/vless/inbound";
option java_package = "com.v2ray.core.proxy.vless.inbound"; option java_package = "com.v2ray.core.proxy.vless.inbound";
option java_multiple_files = true; option java_multiple_files = true;
import "common/net/address.proto";
import "common/protocol/user.proto"; import "common/protocol/user.proto";
message Fallback { message Fallback {
v2ray.core.common.net.IPOrDomain addr = 1; string alpn = 1;
uint32 port = 2; string path = 2;
string unix = 3; string type = 3;
uint32 xver = 4; string dest = 4;
} uint64 xver = 5;
message Fallback_h2 {
v2ray.core.common.net.IPOrDomain addr = 1;
uint32 port = 2;
string unix = 3;
uint32 xver = 4;
} }
message Config { message Config {
repeated v2ray.core.common.protocol.User user = 1; repeated v2ray.core.common.protocol.User clients = 1;
// 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; repeated Fallback fallbacks = 3;
Fallback_h2 fallback_h2 = 4;
} }

View File

@ -51,10 +51,8 @@ type Handler struct {
policyManager policy.Manager policyManager policy.Manager
validator *vless.Validator validator *vless.Validator
dns dns.Client dns dns.Client
fallback *Fallback // or nil fallbacks map[string]map[string]*Fallback // or nil
addrport string //regexps map[string]*regexp.Regexp // or nil
fallback_h2 *FallbackH2 // or nil
addrport_h2 string
} }
// New creates a new VLess inbound handler. // New creates a new VLess inbound handler.
@ -68,7 +66,7 @@ func New(ctx context.Context, config *Config, dc dns.Client) (*Handler, error) {
dns: dc, dns: dc,
} }
for _, user := range config.User { for _, user := range config.Clients {
u, err := user.ToMemoryUser() u, err := user.ToMemoryUser()
if err != nil { if err != nil {
return nil, newError("failed to get VLESS user").Base(err).AtError() return nil, newError("failed to get VLESS user").Base(err).AtError()
@ -78,13 +76,35 @@ func New(ctx context.Context, config *Config, dc dns.Client) (*Handler, error) {
} }
} }
if config.Fallback != nil { if config.Fallbacks != nil {
handler.fallback = config.Fallback handler.fallbacks = make(map[string]map[string]*Fallback)
handler.addrport = handler.fallback.Addr.AsAddress().String() + ":" + strconv.Itoa(int(handler.fallback.Port)) //handler.regexps = make(map[string]*regexp.Regexp)
} for _, fb := range config.Fallbacks {
if config.FallbackH2 != nil { if handler.fallbacks[fb.Alpn] == nil {
handler.fallback_h2 = config.FallbackH2 handler.fallbacks[fb.Alpn] = make(map[string]*Fallback)
handler.addrport_h2 = handler.fallback_h2.Addr.AsAddress().String() + ":" + strconv.Itoa(int(handler.fallback_h2.Port)) }
handler.fallbacks[fb.Alpn][fb.Path] = fb
/*
if fb.Path != "" {
if r, err := regexp.Compile(fb.Path); err != nil {
return nil, newError("invalid path regexp").Base(err).AtError()
} else {
handler.regexps[fb.Path] = r
}
}
*/
}
if handler.fallbacks[""] != nil {
for alpn, pfb := range handler.fallbacks {
if alpn != "" { // && alpn != "h2" {
for path, fb := range handler.fallbacks[""] {
if pfb[path] == nil {
pfb[path] = fb
}
}
}
}
}
} }
return handler, nil return handler, nil
@ -113,6 +133,8 @@ func (*Handler) Network() []net.Network {
// Process implements proxy.Inbound.Process(). // Process implements proxy.Inbound.Process().
func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher routing.Dispatcher) error { func (h *Handler) Process(ctx context.Context, network net.Network, connection internet.Connection, dispatcher routing.Dispatcher) error {
sid := session.ExportIDToError(ctx)
sessionPolicy := h.policyManager.ForLevel(0) sessionPolicy := h.policyManager.ForLevel(0)
if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil { if err := connection.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {
return newError("unable to set read deadline").Base(err).AtWarning() return newError("unable to set read deadline").Base(err).AtWarning()
@ -121,8 +143,8 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
first := buf.New() first := buf.New()
first.ReadFrom(connection) first.ReadFrom(connection)
sid := session.ExportIDToError(ctx) firstLen := first.Len()
newError("firstLen = ", first.Len()).AtInfo().WriteToLog(sid) newError("firstLen = ", firstLen).AtInfo().WriteToLog(sid)
reader := &buf.BufferedReader{ reader := &buf.BufferedReader{
Reader: buf.NewReader(connection), Reader: buf.NewReader(connection),
@ -134,81 +156,124 @@ 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
fallback := 0 isfb := false
if h.fallback != nil { apfb := h.fallbacks
fallback = 1 if apfb != nil {
isfb = true
} }
if fallback == 1 && first.Len() < 18 { if isfb && firstLen < 18 {
err = newError("fallback directly") err = newError("fallback directly")
} else { } else {
request, requestAddons, err, pre = encoding.DecodeRequestHeader(reader, h.validator) request, requestAddons, err, pre = encoding.DecodeRequestHeader(reader, h.validator)
if pre == nil { if pre == nil {
fallback = 0 isfb = false
} }
} }
if err != nil { if err != nil {
if fallback == 1 { if isfb {
if h.fallback_h2 != nil { if err := connection.SetReadDeadline(time.Time{}); err != nil {
newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid)
}
newError("fallback starts").Base(err).AtInfo().WriteToLog(sid)
alpn := ""
if len(apfb) > 1 || apfb[""] == nil {
iConn := connection iConn := connection
if statConn, ok := iConn.(*internet.StatCouterConnection); ok { if statConn, ok := iConn.(*internet.StatCouterConnection); ok {
iConn = statConn.Connection iConn = statConn.Connection
} }
if tlsConn, ok := iConn.(*tls.Conn); ok { if tlsConn, ok := iConn.(*tls.Conn); ok {
if tlsConn.ConnectionState().NegotiatedProtocol == "h2" { alpn = tlsConn.ConnectionState().NegotiatedProtocol
fallback = 2 newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid)
if apfb[alpn] == nil {
alpn = ""
} }
} }
} }
pfb := apfb[alpn]
var addrport string if pfb == nil {
var unixpath string return newError(`failed to find the default "alpn" config`).AtWarning()
var proxyver uint32
switch fallback {
case 1:
addrport = h.addrport
unixpath = h.fallback.Unix
proxyver = h.fallback.Xver
newError("fallback starts").Base(err).AtInfo().WriteToLog(sid)
case 2:
addrport = h.addrport_h2
unixpath = h.fallback_h2.Unix
proxyver = h.fallback_h2.Xver
newError("fallback_h2 starts").Base(err).AtInfo().WriteToLog(sid)
} }
path := ""
if len(pfb) > 1 || pfb[""] == nil {
/*
if lines := bytes.Split(firstBytes, []byte{'\r', '\n'}); len(lines) > 1 {
if s := bytes.Split(lines[0], []byte{' '}); len(s) == 3 {
if len(s[0]) < 8 && len(s[1]) > 0 && len(s[2]) == 8 {
newError("realPath = " + string(s[1])).AtInfo().WriteToLog(sid)
for _, fb := range pfb {
if fb.Path != "" && h.regexps[fb.Path].Match(s[1]) {
path = fb.Path
break
}
}
}
}
}
*/
if pre != nil && pre.Len() == 1 && first.Byte(3) != '*' { // firstLen >= 18 && invalid request version && not h2c
firstBytes := first.Bytes()
for i := 3; i <= 7; i++ { // 5 -> 9
if firstBytes[i] == '/' && firstBytes[i-1] == ' ' {
search := len(firstBytes)
if search > 64 {
search = 64 // up to 60
}
for j := i + 1; j < search; j++ {
k := firstBytes[j]
if k == '\r' || k == '\n' { // avoid logging \r or \n
break
}
if k == ' ' {
path = string(firstBytes[i:j])
newError("realPath = " + path).AtInfo().WriteToLog(sid)
if pfb[path] == nil {
path = ""
}
break
}
}
break
}
}
}
}
fb := pfb[path]
if fb == nil {
return newError(`failed to find the default "path" config`).AtWarning()
}
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)
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 conn, err = dialer.DialContext(ctx, fb.Type, fb.Dest)
if unixpath != "" {
conn, err = dialer.DialContext(ctx, "unix", unixpath)
} else {
conn, err = dialer.DialContext(ctx, "tcp", addrport)
}
if err != nil { if err != nil {
return err return err
} }
return nil return nil
}); err != nil { }); err != nil {
return newError("failed to fallback connection").Base(err).AtWarning() dest := fb.Dest
if dest[0] == '\x00' {
dest = "@" + dest[1:]
}
return newError("failed to dial to " + dest).Base(err).AtWarning()
} }
defer conn.Close() // nolint: errcheck defer conn.Close() // nolint: errcheck
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
writer := buf.NewWriter(connection)
serverReader := buf.NewReader(conn) serverReader := buf.NewReader(conn)
serverWriter := buf.NewWriter(conn) serverWriter := buf.NewWriter(conn)
postRequest := func() error { postRequest := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
if proxyver > 0 { if fb.Xver != 0 {
remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String()) remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String())
if err != nil { if err != nil {
return err return err
@ -225,7 +290,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
} }
} }
pro := buf.New() pro := buf.New()
switch proxyver { switch fb.Xver {
case 1: case 1:
if ipv4 { if ipv4 {
pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n")) pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))
@ -257,7 +322,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
pro.Write(b2) pro.Write(b2)
} }
if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil { if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil {
return newError("failed to set PROXY protocol v", proxyver).Base(err).AtWarning() return newError("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning()
} }
} }
if pre != nil && pre.Len() > 0 { if pre != nil && pre.Len() > 0 {
@ -266,15 +331,17 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
} }
} }
if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil {
return err // ... return newError("failed to fallback request payload").Base(err).AtInfo()
} }
return nil return nil
} }
writer := buf.NewWriter(connection)
getResponse := func() error { getResponse := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil {
return err // ... return newError("failed to deliver response payload").Base(err).AtInfo()
} }
return nil return nil
} }
@ -299,6 +366,17 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
return err return err
} }
if err := connection.SetReadDeadline(time.Time{}); err != nil {
newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid)
}
newError("received request for ", request.Destination()).AtInfo().WriteToLog(sid)
inbound := session.InboundFromContext(ctx)
if inbound == nil {
panic("no inbound metadata")
}
inbound.User = request.User
if request.Command != protocol.RequestCommandMux { if request.Command != protocol.RequestCommandMux {
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
From: connection.RemoteAddr(), From: connection.RemoteAddr(),
@ -309,24 +387,11 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection i
}) })
} }
newError("received request for ", request.Destination()).AtInfo().WriteToLog(sid)
if err := connection.SetReadDeadline(time.Time{}); err != nil {
newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid)
}
inbound := session.InboundFromContext(ctx)
if inbound == nil {
panic("no inbound metadata")
}
inbound.User = request.User
sessionPolicy = h.policyManager.ForLevel(request.User.Level) sessionPolicy = h.policyManager.ForLevel(request.User.Level)
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)
link, err := dispatcher.Dispatch(ctx, request.Destination()) link, err := dispatcher.Dispatch(ctx, request.Destination())
if err != nil { if err != nil {
return newError("failed to dispatch request to ", request.Destination()).Base(err).AtWarning() return newError("failed to dispatch request to ", request.Destination()).Base(err).AtWarning()

View File

@ -31,7 +31,7 @@ type Config struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Receiver []*protocol.ServerEndpoint `protobuf:"bytes,1,rep,name=receiver,proto3" json:"receiver,omitempty"` Vnext []*protocol.ServerEndpoint `protobuf:"bytes,1,rep,name=vnext,proto3" json:"vnext,omitempty"`
} }
func (x *Config) Reset() { func (x *Config) Reset() {
@ -66,9 +66,9 @@ func (*Config) Descriptor() ([]byte, []int) {
return file_proxy_vless_outbound_config_proto_rawDescGZIP(), []int{0} return file_proxy_vless_outbound_config_proto_rawDescGZIP(), []int{0}
} }
func (x *Config) GetReceiver() []*protocol.ServerEndpoint { func (x *Config) GetVnext() []*protocol.ServerEndpoint {
if x != nil { if x != nil {
return x.Receiver return x.Vnext
} }
return nil return nil
} }
@ -82,20 +82,19 @@ var file_proxy_vless_outbound_config_proto_rawDesc = []byte{
0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x6f, 0x75, 0x74, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x6f, 0x75, 0x74, 0x62,
0x6f, 0x75, 0x6e, 0x64, 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x6f, 0x75, 0x6e, 0x64, 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65,
0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x50, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4a, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x12, 0x46, 0x0a, 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x67, 0x12, 0x40, 0x0a, 0x05, 0x76, 0x6e, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x32, 0x2a, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65,
0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x72, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x6e,
0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x42, 0x6e, 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x65, 0x78, 0x74, 0x42, 0x6e, 0x0a, 0x23, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79,
0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73,
0x79, 0x2e, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x2e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x23, 0x76, 0x32,
0x50, 0x01, 0x5a, 0x23, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f,
0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2f, 0x6f, 0x78, 0x79, 0x2f, 0x76, 0x6c, 0x65, 0x73, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e,
0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0xaa, 0x02, 0x1f, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x64, 0xaa, 0x02, 0x1f, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50,
0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x56, 0x6c, 0x65, 0x73, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x62, 0x6f,
0x2e, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x75, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x33,
} }
var ( var (
@ -116,7 +115,7 @@ var file_proxy_vless_outbound_config_proto_goTypes = []interface{}{
(*protocol.ServerEndpoint)(nil), // 1: v2ray.core.common.protocol.ServerEndpoint (*protocol.ServerEndpoint)(nil), // 1: v2ray.core.common.protocol.ServerEndpoint
} }
var file_proxy_vless_outbound_config_proto_depIdxs = []int32{ var file_proxy_vless_outbound_config_proto_depIdxs = []int32{
1, // 0: v2ray.core.proxy.vless.outbound.Config.receiver:type_name -> v2ray.core.common.protocol.ServerEndpoint 1, // 0: v2ray.core.proxy.vless.outbound.Config.vnext:type_name -> v2ray.core.common.protocol.ServerEndpoint
1, // [1:1] is the sub-list for method output_type 1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type 1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name 1, // [1:1] is the sub-list for extension type_name

View File

@ -9,5 +9,5 @@ option java_multiple_files = true;
import "common/protocol/server_spec.proto"; import "common/protocol/server_spec.proto";
message Config { message Config {
repeated v2ray.core.common.protocol.ServerEndpoint receiver = 1; repeated v2ray.core.common.protocol.ServerEndpoint vnext = 1;
} }

View File

@ -41,7 +41,7 @@ type Handler struct {
func New(ctx context.Context, config *Config) (*Handler, error) { func New(ctx context.Context, config *Config) (*Handler, error) {
serverList := protocol.NewServerList() serverList := protocol.NewServerList()
for _, rec := range config.Receiver { for _, rec := range config.Vnext {
s, err := protocol.NewServerSpecFromPB(rec) s, err := protocol.NewServerSpecFromPB(rec)
if err != nil { if err != nil {
return nil, newError("failed to parse server spec").Base(err).AtError() return nil, newError("failed to parse server spec").Base(err).AtError()
@ -109,7 +109,6 @@ func (v *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
} }
sessionPolicy := v.policyManager.ForLevel(request.User.Level) sessionPolicy := v.policyManager.ForLevel(request.User.Level)
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)