mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 09:36:34 -05:00
Refactor vmess config
This commit is contained in:
parent
f10f08c87d
commit
771d0225c7
@ -8,7 +8,7 @@ import (
|
||||
"github.com/v2ray/v2ray-core/config/json"
|
||||
_ "github.com/v2ray/v2ray-core/proxy/freedom/config/json"
|
||||
_ "github.com/v2ray/v2ray-core/proxy/socks/config/json"
|
||||
_ "github.com/v2ray/v2ray-core/proxy/vmess"
|
||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/config/json"
|
||||
|
||||
"github.com/v2ray/v2ray-core/testing/unit"
|
||||
)
|
||||
|
@ -1,84 +0,0 @@
|
||||
package vmess
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/log"
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
"github.com/v2ray/v2ray-core/config"
|
||||
"github.com/v2ray/v2ray-core/config/json"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
|
||||
)
|
||||
|
||||
// VMessUser is an authenticated user account in VMess configuration.
|
||||
type VMessUser struct {
|
||||
Id string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
func (u *VMessUser) ToUser() (user.User, error) {
|
||||
id, err := user.NewID(u.Id)
|
||||
return user.User{
|
||||
Id: id,
|
||||
}, err
|
||||
}
|
||||
|
||||
// VMessInboundConfig is
|
||||
type VMessInboundConfig struct {
|
||||
AllowedClients []VMessUser `json:"clients"`
|
||||
UDPEnabled bool `json:"udp"`
|
||||
}
|
||||
|
||||
type VNextConfig struct {
|
||||
Address string `json:"address"`
|
||||
Port uint16 `json:"port"`
|
||||
Users []VMessUser `json:"users"`
|
||||
Network string `json:"network"`
|
||||
}
|
||||
|
||||
func (config VNextConfig) HasNetwork(network string) bool {
|
||||
return strings.Contains(config.Network, network)
|
||||
}
|
||||
|
||||
func (c VNextConfig) ToVNextServer(network string) (*VNextServer, error) {
|
||||
users := make([]user.User, 0, len(c.Users))
|
||||
for _, user := range c.Users {
|
||||
vuser, err := user.ToUser()
|
||||
if err != nil {
|
||||
log.Error("Failed to convert %v to User.", user)
|
||||
return nil, config.BadConfiguration
|
||||
}
|
||||
users = append(users, vuser)
|
||||
}
|
||||
ip := net.ParseIP(c.Address)
|
||||
if ip == nil {
|
||||
log.Error("Unable to parse VNext IP: %s", c.Address)
|
||||
return nil, config.BadConfiguration
|
||||
}
|
||||
address := v2net.IPAddress(ip, c.Port)
|
||||
var dest v2net.Destination
|
||||
if network == "tcp" {
|
||||
dest = v2net.NewTCPDestination(address)
|
||||
} else {
|
||||
dest = v2net.NewUDPDestination(address)
|
||||
}
|
||||
return &VNextServer{
|
||||
Destination: dest,
|
||||
Users: users,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type VMessOutboundConfig struct {
|
||||
VNextList []VNextConfig `json:"vnext"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
json.RegisterConfigType("vmess", config.TypeInbound, func() interface{} {
|
||||
return new(VMessInboundConfig)
|
||||
})
|
||||
|
||||
json.RegisterConfigType("vmess", config.TypeOutbound, func() interface{} {
|
||||
return new(VMessOutboundConfig)
|
||||
})
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package user
|
||||
package config
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
@ -23,11 +23,11 @@ type ID struct {
|
||||
cmdKey [IDBytesLen]byte
|
||||
}
|
||||
|
||||
func NewID(id string) (ID, error) {
|
||||
func NewID(id string) (*ID, error) {
|
||||
idBytes, err := UUIDToID(id)
|
||||
if err != nil {
|
||||
log.Error("Failed to parse id %s", id)
|
||||
return ID{}, InvalidID
|
||||
return &ID{}, InvalidID
|
||||
}
|
||||
|
||||
md5hash := md5.New()
|
||||
@ -35,7 +35,7 @@ func NewID(id string) (ID, error) {
|
||||
md5hash.Write([]byte("c48619fe-8f02-49e0-b9e9-edf763e17e21"))
|
||||
cmdKey := md5.Sum(nil)
|
||||
|
||||
return ID{
|
||||
return &ID{
|
||||
String: id,
|
||||
Bytes: idBytes,
|
||||
cmdKey: cmdKey,
|
@ -1,4 +1,4 @@
|
||||
package user
|
||||
package config
|
||||
|
||||
import (
|
||||
"testing"
|
6
proxy/vmess/config/inbound.go
Normal file
6
proxy/vmess/config/inbound.go
Normal file
@ -0,0 +1,6 @@
|
||||
package config
|
||||
|
||||
type Inbound interface {
|
||||
AllowedUsers() []User
|
||||
UDPEnabled() bool
|
||||
}
|
30
proxy/vmess/config/json/inbound.go
Normal file
30
proxy/vmess/config/json/inbound.go
Normal file
@ -0,0 +1,30 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"github.com/v2ray/v2ray-core/config"
|
||||
"github.com/v2ray/v2ray-core/config/json"
|
||||
vmessconfig "github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
)
|
||||
|
||||
type Inbound struct {
|
||||
AllowedClients []*ConfigUser `json:"clients"`
|
||||
UDP bool `json:"udp"`
|
||||
}
|
||||
|
||||
func (c *Inbound) AllowedUsers() []vmessconfig.User {
|
||||
users := make([]vmessconfig.User, 0, len(c.AllowedClients))
|
||||
for _, rawUser := range c.AllowedClients {
|
||||
users = append(users, rawUser)
|
||||
}
|
||||
return users
|
||||
}
|
||||
|
||||
func (c *Inbound) UDPEnabled() bool {
|
||||
return c.UDP
|
||||
}
|
||||
|
||||
func init() {
|
||||
json.RegisterConfigType("vmess", config.TypeInbound, func() interface{} {
|
||||
return new(Inbound)
|
||||
})
|
||||
}
|
84
proxy/vmess/config/json/outbound.go
Normal file
84
proxy/vmess/config/json/outbound.go
Normal file
@ -0,0 +1,84 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/log"
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
"github.com/v2ray/v2ray-core/config"
|
||||
jsonconfig "github.com/v2ray/v2ray-core/config/json"
|
||||
vmessconfig "github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
)
|
||||
|
||||
type RawConfigTarget struct {
|
||||
Address string `json:"address"`
|
||||
Port uint16 `json:"port"`
|
||||
Users []*ConfigUser `json:"users"`
|
||||
Network string `json:"network"`
|
||||
}
|
||||
|
||||
func (config RawConfigTarget) HasNetwork(network string) bool {
|
||||
return strings.Contains(config.Network, network)
|
||||
}
|
||||
|
||||
type ConfigTarget struct {
|
||||
Address v2net.Address
|
||||
Users []*ConfigUser
|
||||
TCPEnabled bool
|
||||
UDPEnabled bool
|
||||
}
|
||||
|
||||
func (t *ConfigTarget) UnmarshalJSON(data []byte) error {
|
||||
var rawConfig RawConfigTarget
|
||||
if err := json.Unmarshal(data, &rawConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
ip := net.ParseIP(rawConfig.Address)
|
||||
if ip == nil {
|
||||
log.Error("Unable to parse IP: %s", rawConfig.Address)
|
||||
return config.BadConfiguration
|
||||
}
|
||||
t.Address = v2net.IPAddress(ip, rawConfig.Port)
|
||||
if rawConfig.HasNetwork("tcp") {
|
||||
t.TCPEnabled = true
|
||||
}
|
||||
if rawConfig.HasNetwork("udp") {
|
||||
t.UDPEnabled = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Outbound struct {
|
||||
TargetList []*ConfigTarget `json:"vnext"`
|
||||
}
|
||||
|
||||
func (o *Outbound) Targets() []*vmessconfig.OutboundTarget {
|
||||
targets := make([]*vmessconfig.OutboundTarget, 0, 2*len(o.TargetList))
|
||||
for _, rawTarget := range o.TargetList {
|
||||
users := make([]vmessconfig.User, 0, len(rawTarget.Users))
|
||||
for _, rawUser := range rawTarget.Users {
|
||||
users = append(users, rawUser)
|
||||
}
|
||||
if rawTarget.TCPEnabled {
|
||||
targets = append(targets, &vmessconfig.OutboundTarget{
|
||||
Destination: v2net.NewTCPDestination(rawTarget.Address),
|
||||
Accounts: users,
|
||||
})
|
||||
}
|
||||
if rawTarget.UDPEnabled {
|
||||
targets = append(targets, &vmessconfig.OutboundTarget{
|
||||
Destination: v2net.NewUDPDestination(rawTarget.Address),
|
||||
Accounts: users,
|
||||
})
|
||||
}
|
||||
}
|
||||
return targets
|
||||
}
|
||||
|
||||
func init() {
|
||||
jsonconfig.RegisterConfigType("vmess", config.TypeOutbound, func() interface{} {
|
||||
return new(Outbound)
|
||||
})
|
||||
}
|
35
proxy/vmess/config/json/user.go
Normal file
35
proxy/vmess/config/json/user.go
Normal file
@ -0,0 +1,35 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
)
|
||||
|
||||
// ConfigUser is an user account in VMess configuration.
|
||||
type ConfigUser struct {
|
||||
Id *config.ID
|
||||
Email string
|
||||
}
|
||||
|
||||
func (u *ConfigUser) UnmarshalJSON(data []byte) error {
|
||||
type rawUser struct {
|
||||
IdString string `json:"id"`
|
||||
EmailString string `json:"email"`
|
||||
}
|
||||
var rawUserValue rawUser
|
||||
if err := json.Unmarshal(data, &rawUserValue); err != nil {
|
||||
return err
|
||||
}
|
||||
id, err := config.NewID(rawUserValue.IdString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Id = id
|
||||
u.Email = rawUserValue.EmailString
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *ConfigUser) ID() *config.ID {
|
||||
return u.Id
|
||||
}
|
14
proxy/vmess/config/outbound.go
Normal file
14
proxy/vmess/config/outbound.go
Normal file
@ -0,0 +1,14 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
)
|
||||
|
||||
type OutboundTarget struct {
|
||||
Destination v2net.Destination
|
||||
Accounts []User
|
||||
}
|
||||
|
||||
type Outbound interface {
|
||||
Targets() []*OutboundTarget
|
||||
}
|
5
proxy/vmess/config/user.go
Normal file
5
proxy/vmess/config/user.go
Normal file
@ -0,0 +1,5 @@
|
||||
package config
|
||||
|
||||
type User interface {
|
||||
ID() *ID
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package user
|
||||
|
||||
// User is the user account that is used for connection to a Point
|
||||
type User struct {
|
||||
Id ID `json:"id"` // The ID of this User.
|
||||
}
|
@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/collect"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -13,12 +14,12 @@ const (
|
||||
)
|
||||
|
||||
type UserSet interface {
|
||||
AddUser(user User) error
|
||||
GetUser(timeHash []byte) (*ID, int64, bool)
|
||||
AddUser(user config.User) error
|
||||
GetUser(timeHash []byte) (*config.ID, int64, bool)
|
||||
}
|
||||
|
||||
type TimedUserSet struct {
|
||||
validUserIds []ID
|
||||
validUserIds []*config.ID
|
||||
userHash map[string]indexTimePair
|
||||
userHashDeleteQueue *collect.TimedQueue
|
||||
access sync.RWMutex
|
||||
@ -31,7 +32,7 @@ type indexTimePair struct {
|
||||
|
||||
func NewTimedUserSet() UserSet {
|
||||
tus := &TimedUserSet{
|
||||
validUserIds: make([]ID, 0, 16),
|
||||
validUserIds: make([]*config.ID, 0, 16),
|
||||
userHash: make(map[string]indexTimePair, 512),
|
||||
userHashDeleteQueue: collect.NewTimedQueue(updateIntervalSec),
|
||||
access: sync.RWMutex{},
|
||||
@ -49,7 +50,7 @@ func (us *TimedUserSet) removeEntries(entries <-chan interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func (us *TimedUserSet) generateNewHashes(lastSec, nowSec int64, idx int, id ID) {
|
||||
func (us *TimedUserSet) generateNewHashes(lastSec, nowSec int64, idx int, id *config.ID) {
|
||||
idHash := NewTimeHash(HMACHash{})
|
||||
for lastSec < nowSec {
|
||||
idHash := idHash.Hash(id.Bytes[:], lastSec)
|
||||
@ -73,8 +74,8 @@ func (us *TimedUserSet) updateUserHash(tick <-chan time.Time) {
|
||||
}
|
||||
}
|
||||
|
||||
func (us *TimedUserSet) AddUser(user User) error {
|
||||
id := user.Id
|
||||
func (us *TimedUserSet) AddUser(user config.User) error {
|
||||
id := user.ID()
|
||||
idx := len(us.validUserIds)
|
||||
us.validUserIds = append(us.validUserIds, id)
|
||||
|
||||
@ -85,12 +86,12 @@ func (us *TimedUserSet) AddUser(user User) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (us TimedUserSet) GetUser(userHash []byte) (*ID, int64, bool) {
|
||||
func (us TimedUserSet) GetUser(userHash []byte) (*config.ID, int64, bool) {
|
||||
defer us.access.RUnlock()
|
||||
us.access.RLock()
|
||||
pair, found := us.userHash[string(userHash)]
|
||||
if found {
|
||||
return &us.validUserIds[pair.index], pair.timeSec, true
|
||||
return us.validUserIds[pair.index], pair.timeSec, true
|
||||
}
|
||||
return nil, 0, false
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/v2ray/v2ray-core/common/log"
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
"github.com/v2ray/v2ray-core/proxy"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
|
||||
"github.com/v2ray/v2ray-core/transport"
|
||||
)
|
||||
@ -35,7 +36,7 @@ const (
|
||||
// streaming.
|
||||
type VMessRequest struct {
|
||||
Version byte
|
||||
UserId user.ID
|
||||
UserId config.ID
|
||||
RequestIV []byte
|
||||
RequestKey []byte
|
||||
ResponseHeader []byte
|
||||
@ -68,7 +69,7 @@ func NewVMessRequestReader(vUserSet user.UserSet) *VMessRequestReader {
|
||||
func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
||||
buffer := make([]byte, 256)
|
||||
|
||||
nBytes, err := reader.Read(buffer[:user.IDBytesLen])
|
||||
nBytes, err := reader.Read(buffer[:config.IDBytesLen])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -6,25 +6,34 @@ import (
|
||||
"testing"
|
||||
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
|
||||
"github.com/v2ray/v2ray-core/testing/mocks"
|
||||
"github.com/v2ray/v2ray-core/testing/unit"
|
||||
)
|
||||
|
||||
type TestUser struct {
|
||||
id *config.ID
|
||||
}
|
||||
|
||||
func (u *TestUser) ID() *config.ID {
|
||||
return u.id
|
||||
}
|
||||
|
||||
func TestVMessSerialization(t *testing.T) {
|
||||
assert := unit.Assert(t)
|
||||
|
||||
userId, err := user.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
||||
userId, err := config.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
userSet := mocks.MockUserSet{[]user.ID{}, make(map[string]int), make(map[string]int64)}
|
||||
userSet.AddUser(user.User{userId})
|
||||
userSet := mocks.MockUserSet{[]*config.ID{}, make(map[string]int), make(map[string]int64)}
|
||||
userSet.AddUser(&TestUser{userId})
|
||||
|
||||
request := new(VMessRequest)
|
||||
request.Version = byte(0x01)
|
||||
request.UserId = userId
|
||||
request.UserId = *userId
|
||||
|
||||
randBytes := make([]byte, 36)
|
||||
_, err = rand.Read(randBytes)
|
||||
@ -61,13 +70,13 @@ func TestVMessSerialization(t *testing.T) {
|
||||
}
|
||||
|
||||
func BenchmarkVMessRequestWriting(b *testing.B) {
|
||||
userId, _ := user.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
||||
userSet := mocks.MockUserSet{[]user.ID{}, make(map[string]int), make(map[string]int64)}
|
||||
userSet.AddUser(user.User{userId})
|
||||
userId, _ := config.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
||||
userSet := mocks.MockUserSet{[]*config.ID{}, make(map[string]int), make(map[string]int64)}
|
||||
userSet.AddUser(&TestUser{userId})
|
||||
|
||||
request := new(VMessRequest)
|
||||
request.Version = byte(0x01)
|
||||
request.UserId = userId
|
||||
request.UserId = *userId
|
||||
|
||||
randBytes := make([]byte, 36)
|
||||
rand.Read(randBytes)
|
||||
|
@ -8,6 +8,8 @@ import (
|
||||
"github.com/v2ray/v2ray-core/common/alloc"
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
"github.com/v2ray/v2ray-core/proxy"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config/json"
|
||||
"github.com/v2ray/v2ray-core/testing/mocks"
|
||||
"github.com/v2ray/v2ray-core/testing/unit"
|
||||
)
|
||||
@ -16,6 +18,8 @@ func TestVMessInAndOut(t *testing.T) {
|
||||
assert := unit.Assert(t)
|
||||
|
||||
data2Send := "The data to be send to outbound server."
|
||||
testAccount, err := config.NewID("ad937d9d-6e23-4a5a-ba23-bce5092a7c51")
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
portA := uint16(17392)
|
||||
ich := &mocks.InboundConnectionHandler{
|
||||
@ -33,14 +37,13 @@ func TestVMessInAndOut(t *testing.T) {
|
||||
},
|
||||
OutboundConfigValue: &mocks.ConnectionConfig{
|
||||
ProtocolValue: "vmess",
|
||||
SettingsValue: &VMessOutboundConfig{
|
||||
[]VNextConfig{
|
||||
VNextConfig{
|
||||
Address: "127.0.0.1",
|
||||
Port: 13829,
|
||||
Network: "tcp",
|
||||
Users: []VMessUser{
|
||||
VMessUser{Id: "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"},
|
||||
SettingsValue: &json.Outbound{
|
||||
[]*json.ConfigTarget{
|
||||
&json.ConfigTarget{
|
||||
Address: v2net.IPAddress([]byte{127, 0, 0, 1}, 13829),
|
||||
TCPEnabled: true,
|
||||
Users: []*json.ConfigUser{
|
||||
&json.ConfigUser{Id: testAccount},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -67,9 +70,9 @@ func TestVMessInAndOut(t *testing.T) {
|
||||
PortValue: portB,
|
||||
InboundConfigValue: &mocks.ConnectionConfig{
|
||||
ProtocolValue: "vmess",
|
||||
SettingsValue: &VMessInboundConfig{
|
||||
AllowedClients: []VMessUser{
|
||||
VMessUser{Id: "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"},
|
||||
SettingsValue: &json.Inbound{
|
||||
AllowedClients: []*json.ConfigUser{
|
||||
&json.ConfigUser{Id: testAccount},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -95,6 +98,8 @@ func TestVMessInAndOutUDP(t *testing.T) {
|
||||
assert := unit.Assert(t)
|
||||
|
||||
data2Send := "The data to be send to outbound server."
|
||||
testAccount, err := config.NewID("ad937d9d-6e23-4a5a-ba23-bce5092a7c51")
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
portA := uint16(17394)
|
||||
ich := &mocks.InboundConnectionHandler{
|
||||
@ -112,14 +117,13 @@ func TestVMessInAndOutUDP(t *testing.T) {
|
||||
},
|
||||
OutboundConfigValue: &mocks.ConnectionConfig{
|
||||
ProtocolValue: "vmess",
|
||||
SettingsValue: &VMessOutboundConfig{
|
||||
[]VNextConfig{
|
||||
VNextConfig{
|
||||
Address: "127.0.0.1",
|
||||
Port: 13841,
|
||||
Network: "udp",
|
||||
Users: []VMessUser{
|
||||
VMessUser{Id: "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"},
|
||||
SettingsValue: &json.Outbound{
|
||||
[]*json.ConfigTarget{
|
||||
&json.ConfigTarget{
|
||||
Address: v2net.IPAddress([]byte{127, 0, 0, 1}, 13841),
|
||||
UDPEnabled: true,
|
||||
Users: []*json.ConfigUser{
|
||||
&json.ConfigUser{Id: testAccount},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -146,11 +150,11 @@ func TestVMessInAndOutUDP(t *testing.T) {
|
||||
PortValue: portB,
|
||||
InboundConfigValue: &mocks.ConnectionConfig{
|
||||
ProtocolValue: "vmess",
|
||||
SettingsValue: &VMessInboundConfig{
|
||||
AllowedClients: []VMessUser{
|
||||
VMessUser{Id: "ad937d9d-6e23-4a5a-ba23-bce5092a7c51"},
|
||||
SettingsValue: &json.Inbound{
|
||||
AllowedClients: []*json.ConfigUser{
|
||||
&json.ConfigUser{Id: testAccount},
|
||||
},
|
||||
UDPEnabled: true,
|
||||
UDP: true,
|
||||
},
|
||||
},
|
||||
OutboundConfigValue: &mocks.ConnectionConfig{
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
"github.com/v2ray/v2ray-core/common/retry"
|
||||
"github.com/v2ray/v2ray-core/proxy"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
|
||||
)
|
||||
@ -142,19 +143,14 @@ type VMessInboundHandlerFactory struct {
|
||||
}
|
||||
|
||||
func (factory *VMessInboundHandlerFactory) Create(dispatcher app.PacketDispatcher, rawConfig interface{}) (proxy.InboundConnectionHandler, error) {
|
||||
config := rawConfig.(*VMessInboundConfig)
|
||||
config := rawConfig.(config.Inbound)
|
||||
|
||||
allowedClients := user.NewTimedUserSet()
|
||||
for _, client := range config.AllowedClients {
|
||||
user, err := client.ToUser()
|
||||
if err != nil {
|
||||
log.Error("VMessIn: Failed to parse user id %s: %v", client.Id, err)
|
||||
return nil, err
|
||||
}
|
||||
for _, user := range config.AllowedUsers() {
|
||||
allowedClients.AddUser(user)
|
||||
}
|
||||
|
||||
return NewVMessInboundHandler(dispatcher, allowedClients, config.UDPEnabled), nil
|
||||
return NewVMessInboundHandler(dispatcher, allowedClients, config.UDPEnabled()), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/v2ray/v2ray-core/common/log"
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
"github.com/v2ray/v2ray-core/proxy"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
|
||||
"github.com/v2ray/v2ray-core/transport/ray"
|
||||
@ -22,25 +23,19 @@ const (
|
||||
InfoTimeNotSync = "Please check the User ID in your vmess configuration, and make sure the time on your local and remote server are in sync."
|
||||
)
|
||||
|
||||
// VNext is the next Point server in the connection chain.
|
||||
type VNextServer struct {
|
||||
Destination v2net.Destination // Address of VNext server
|
||||
Users []user.User // User accounts for accessing VNext.
|
||||
}
|
||||
|
||||
type VMessOutboundHandler struct {
|
||||
vNextList []*VNextServer
|
||||
vNextListUDP []*VNextServer
|
||||
vNextList []*config.OutboundTarget
|
||||
vNextListUDP []*config.OutboundTarget
|
||||
}
|
||||
|
||||
func NewVMessOutboundHandler(vNextList, vNextListUDP []*VNextServer) *VMessOutboundHandler {
|
||||
func NewVMessOutboundHandler(vNextList, vNextListUDP []*config.OutboundTarget) *VMessOutboundHandler {
|
||||
return &VMessOutboundHandler{
|
||||
vNextList: vNextList,
|
||||
vNextListUDP: vNextListUDP,
|
||||
}
|
||||
}
|
||||
|
||||
func pickVNext(serverList []*VNextServer) (v2net.Destination, user.User) {
|
||||
func pickVNext(serverList []*config.OutboundTarget) (v2net.Destination, config.User) {
|
||||
vNextLen := len(serverList)
|
||||
if vNextLen == 0 {
|
||||
panic("VMessOut: Zero vNext is configured.")
|
||||
@ -51,7 +46,7 @@ func pickVNext(serverList []*VNextServer) (v2net.Destination, user.User) {
|
||||
}
|
||||
|
||||
vNext := serverList[vNextIndex]
|
||||
vNextUserLen := len(vNext.Users)
|
||||
vNextUserLen := len(vNext.Accounts)
|
||||
if vNextUserLen == 0 {
|
||||
panic("VMessOut: Zero User account.")
|
||||
}
|
||||
@ -59,7 +54,7 @@ func pickVNext(serverList []*VNextServer) (v2net.Destination, user.User) {
|
||||
if vNextUserLen > 1 {
|
||||
vNextUserIndex = mrand.Intn(vNextUserLen)
|
||||
}
|
||||
vNextUser := vNext.Users[vNextUserIndex]
|
||||
vNextUser := vNext.Accounts[vNextUserIndex]
|
||||
return vNext.Destination, vNextUser
|
||||
}
|
||||
|
||||
@ -76,7 +71,7 @@ func (handler *VMessOutboundHandler) Dispatch(firstPacket v2net.Packet, ray ray.
|
||||
}
|
||||
request := &protocol.VMessRequest{
|
||||
Version: protocol.Version,
|
||||
UserId: vNextUser.Id,
|
||||
UserId: *vNextUser.ID(),
|
||||
Command: command,
|
||||
Address: firstPacket.Destination().Address(),
|
||||
}
|
||||
@ -199,26 +194,15 @@ type VMessOutboundHandlerFactory struct {
|
||||
}
|
||||
|
||||
func (factory *VMessOutboundHandlerFactory) Create(rawConfig interface{}) (proxy.OutboundConnectionHandler, error) {
|
||||
config := rawConfig.(*VMessOutboundConfig)
|
||||
servers := make([]*VNextServer, 0, len(config.VNextList))
|
||||
udpServers := make([]*VNextServer, 0, len(config.VNextList))
|
||||
for _, server := range config.VNextList {
|
||||
if server.HasNetwork("tcp") {
|
||||
aServer, err := server.ToVNextServer("tcp")
|
||||
if err == nil {
|
||||
servers = append(servers, aServer)
|
||||
} else {
|
||||
log.Warning("Discarding the server.")
|
||||
vOutConfig := rawConfig.(config.Outbound)
|
||||
servers := make([]*config.OutboundTarget, 0, 16)
|
||||
udpServers := make([]*config.OutboundTarget, 0, 16)
|
||||
for _, target := range vOutConfig.Targets() {
|
||||
if target.Destination.IsTCP() {
|
||||
servers = append(servers, target)
|
||||
}
|
||||
}
|
||||
if server.HasNetwork("udp") {
|
||||
aServer, err := server.ToVNextServer("udp")
|
||||
if err == nil {
|
||||
udpServers = append(udpServers, aServer)
|
||||
} else {
|
||||
log.Warning("Discarding the server.")
|
||||
}
|
||||
|
||||
if target.Destination.IsUDP() {
|
||||
udpServers = append(udpServers, target)
|
||||
}
|
||||
}
|
||||
return NewVMessOutboundHandler(servers, udpServers), nil
|
||||
|
@ -1,24 +1,24 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
|
||||
"github.com/v2ray/v2ray-core/proxy/vmess/config"
|
||||
)
|
||||
|
||||
type MockUserSet struct {
|
||||
UserIds []user.ID
|
||||
UserIds []*config.ID
|
||||
UserHashes map[string]int
|
||||
Timestamps map[string]int64
|
||||
}
|
||||
|
||||
func (us *MockUserSet) AddUser(user user.User) error {
|
||||
us.UserIds = append(us.UserIds, user.Id)
|
||||
func (us *MockUserSet) AddUser(user config.User) error {
|
||||
us.UserIds = append(us.UserIds, user.ID())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (us *MockUserSet) GetUser(userhash []byte) (*user.ID, int64, bool) {
|
||||
func (us *MockUserSet) GetUser(userhash []byte) (*config.ID, int64, bool) {
|
||||
idx, found := us.UserHashes[string(userhash)]
|
||||
if found {
|
||||
return &us.UserIds[idx], us.Timestamps[string(userhash)], true
|
||||
return us.UserIds[idx], us.Timestamps[string(userhash)], true
|
||||
}
|
||||
return nil, 0, false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user