mirror of https://github.com/v2ray/v2ray-core
use server spec in vmess
parent
b02bd5b1d8
commit
2049759640
|
@ -8,20 +8,60 @@ import (
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerSpec struct {
|
type ValidationStrategy interface {
|
||||||
sync.RWMutex
|
IsValid() bool
|
||||||
Destination v2net.Destination
|
Invalidate()
|
||||||
|
|
||||||
users []*User
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServerSpec(dest v2net.Destination, users ...*User) *ServerSpec {
|
type AlwaysValidStrategy struct{}
|
||||||
return &ServerSpec{
|
|
||||||
Destination: dest,
|
func AlwaysValid() ValidationStrategy {
|
||||||
users: users,
|
return AlwaysValidStrategy{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this AlwaysValidStrategy) IsValid() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this AlwaysValidStrategy) Invalidate() {}
|
||||||
|
|
||||||
|
type TimeoutValidStrategy struct {
|
||||||
|
until time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func BeforeTime(t time.Time) ValidationStrategy {
|
||||||
|
return TimeoutValidStrategy{
|
||||||
|
until: t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this TimeoutValidStrategy) IsValid() bool {
|
||||||
|
return this.until.After(time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this TimeoutValidStrategy) Invalidate() {
|
||||||
|
this.until = time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServerSpec struct {
|
||||||
|
sync.RWMutex
|
||||||
|
dest v2net.Destination
|
||||||
|
users []*User
|
||||||
|
valid ValidationStrategy
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServerSpec(dest v2net.Destination, valid ValidationStrategy, users ...*User) *ServerSpec {
|
||||||
|
return &ServerSpec{
|
||||||
|
dest: dest,
|
||||||
|
users: users,
|
||||||
|
valid: valid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ServerSpec) Destination() v2net.Destination {
|
||||||
|
return this.dest
|
||||||
|
}
|
||||||
|
|
||||||
func (this *ServerSpec) HasUser(user *User) bool {
|
func (this *ServerSpec) HasUser(user *User) bool {
|
||||||
this.RLock()
|
this.RLock()
|
||||||
defer this.RUnlock()
|
defer this.RUnlock()
|
||||||
|
@ -52,30 +92,9 @@ func (this *ServerSpec) PickUser() *User {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSpec) IsValid() bool {
|
func (this *ServerSpec) IsValid() bool {
|
||||||
return true
|
return this.valid.IsValid()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ServerSpec) SetValid(b bool) {
|
func (this *ServerSpec) Invalidate() {
|
||||||
}
|
this.valid.Invalidate()
|
||||||
|
|
||||||
type TimeoutServerSpec struct {
|
|
||||||
*ServerSpec
|
|
||||||
until time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTimeoutServerSpec(spec *ServerSpec, until time.Time) *TimeoutServerSpec {
|
|
||||||
return &TimeoutServerSpec{
|
|
||||||
ServerSpec: spec,
|
|
||||||
until: until,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *TimeoutServerSpec) IsValid() bool {
|
|
||||||
return this.until.Before(time.Now())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *TimeoutServerSpec) SetValid(b bool) {
|
|
||||||
if !b {
|
|
||||||
this.until = time.Time{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package protocol_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
. "github.com/v2ray/v2ray-core/common/protocol"
|
||||||
|
"github.com/v2ray/v2ray-core/common/uuid"
|
||||||
|
"github.com/v2ray/v2ray-core/testing/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestReceiverUser(t *testing.T) {
|
||||||
|
assert := assert.On(t)
|
||||||
|
|
||||||
|
id := NewID(uuid.New())
|
||||||
|
alters := NewAlterIDs(id, 100)
|
||||||
|
account := &VMessAccount{
|
||||||
|
ID: id,
|
||||||
|
AlterIDs: alters,
|
||||||
|
}
|
||||||
|
user := NewUser(account, UserLevel(0), "")
|
||||||
|
rec := NewServerSpec(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80), AlwaysValid(), user)
|
||||||
|
assert.Bool(rec.HasUser(user)).IsTrue()
|
||||||
|
|
||||||
|
id2 := NewID(uuid.New())
|
||||||
|
alters2 := NewAlterIDs(id2, 100)
|
||||||
|
account2 := &VMessAccount{
|
||||||
|
ID: id2,
|
||||||
|
AlterIDs: alters2,
|
||||||
|
}
|
||||||
|
user2 := NewUser(account2, UserLevel(0), "")
|
||||||
|
assert.Bool(rec.HasUser(user2)).IsFalse()
|
||||||
|
|
||||||
|
rec.AddUser(user2)
|
||||||
|
assert.Bool(rec.HasUser(user2)).IsTrue()
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
package outbound
|
package outbound
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
"github.com/v2ray/v2ray-core/common/protocol"
|
"github.com/v2ray/v2ray-core/common/protocol"
|
||||||
)
|
)
|
||||||
|
@ -14,7 +16,8 @@ func (this *VMessOutboundHandler) handleSwitchAccount(cmd *protocol.CommandSwitc
|
||||||
}
|
}
|
||||||
user := protocol.NewUser(account, cmd.Level, "")
|
user := protocol.NewUser(account, cmd.Level, "")
|
||||||
dest := v2net.TCPDestination(cmd.Host, cmd.Port)
|
dest := v2net.TCPDestination(cmd.Host, cmd.Port)
|
||||||
this.receiverManager.AddDetour(NewReceiver(dest, user), cmd.ValidMin)
|
until := time.Now().Add(time.Duration(cmd.ValidMin) * time.Minute)
|
||||||
|
this.serverList.AddServer(protocol.NewServerSpec(dest, protocol.BeforeTime(until), user))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessOutboundHandler) handleCommand(dest v2net.Destination, cmd protocol.ResponseCommand) {
|
func (this *VMessOutboundHandler) handleCommand(dest v2net.Destination, cmd protocol.ResponseCommand) {
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package outbound
|
package outbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/v2ray/v2ray-core/common/protocol"
|
||||||
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Receivers []*Receiver
|
Receivers []*protocol.ServerSpec
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,20 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
"github.com/v2ray/v2ray-core/common/protocol"
|
||||||
|
"github.com/v2ray/v2ray-core/common/serial"
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal"
|
"github.com/v2ray/v2ray-core/proxy/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||||
|
type RawConfigTarget struct {
|
||||||
|
Address *v2net.AddressJson `json:"address"`
|
||||||
|
Port v2net.Port `json:"port"`
|
||||||
|
Users []*protocol.User `json:"users"`
|
||||||
|
}
|
||||||
type RawOutbound struct {
|
type RawOutbound struct {
|
||||||
Receivers []*Receiver `json:"vnext"`
|
Receivers []*RawConfigTarget `json:"vnext"`
|
||||||
}
|
}
|
||||||
rawOutbound := &RawOutbound{}
|
rawOutbound := &RawOutbound{}
|
||||||
err := json.Unmarshal(data, rawOutbound)
|
err := json.Unmarshal(data, rawOutbound)
|
||||||
|
@ -23,7 +31,26 @@ func (this *Config) UnmarshalJSON(data []byte) error {
|
||||||
log.Error("VMessOut: 0 VMess receiver configured.")
|
log.Error("VMessOut: 0 VMess receiver configured.")
|
||||||
return internal.ErrBadConfiguration
|
return internal.ErrBadConfiguration
|
||||||
}
|
}
|
||||||
this.Receivers = rawOutbound.Receivers
|
serverSpecs := make([]*protocol.ServerSpec, len(rawOutbound.Receivers))
|
||||||
|
for idx, rec := range rawOutbound.Receivers {
|
||||||
|
if len(rec.Users) == 0 {
|
||||||
|
log.Error("VMess: 0 user configured for VMess outbound.")
|
||||||
|
return internal.ErrBadConfiguration
|
||||||
|
}
|
||||||
|
if rec.Address == nil {
|
||||||
|
log.Error("VMess: Address is not set in VMess outbound config.")
|
||||||
|
return internal.ErrBadConfiguration
|
||||||
|
}
|
||||||
|
if rec.Address.Address.String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) {
|
||||||
|
rec.Address.Address = v2net.IPAddress(serial.Uint32ToBytes(2891346854, nil))
|
||||||
|
}
|
||||||
|
spec := protocol.NewServerSpec(v2net.TCPDestination(rec.Address.Address, rec.Port), protocol.AlwaysValid())
|
||||||
|
for _, user := range rec.Users {
|
||||||
|
spec.AddUser(user)
|
||||||
|
}
|
||||||
|
serverSpecs[idx] = spec
|
||||||
|
}
|
||||||
|
this.Receivers = serverSpecs
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
// +build json
|
||||||
|
|
||||||
|
package outbound_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
//"github.com/v2ray/v2ray-core/common/protocol"
|
||||||
|
. "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
||||||
|
"github.com/v2ray/v2ray-core/testing/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConfigTargetParsing(t *testing.T) {
|
||||||
|
assert := assert.On(t)
|
||||||
|
|
||||||
|
rawJson := `{
|
||||||
|
"vnext": [{
|
||||||
|
"address": "127.0.0.1",
|
||||||
|
"port": 80,
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"id": "e641f5ad-9397-41e3-bf1a-e8740dfed019",
|
||||||
|
"email": "love@v2ray.com",
|
||||||
|
"level": 255
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}`
|
||||||
|
|
||||||
|
config := new(Config)
|
||||||
|
err := json.Unmarshal([]byte(rawJson), &config)
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
assert.Destination(config.Receivers[0].Destination()).EqualsString("tcp:127.0.0.1:80")
|
||||||
|
}
|
|
@ -20,20 +20,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type VMessOutboundHandler struct {
|
type VMessOutboundHandler struct {
|
||||||
receiverManager *ReceiverManager
|
serverList *protocol.ServerList
|
||||||
meta *proxy.OutboundHandlerMeta
|
serverPicker protocol.ServerPicker
|
||||||
|
meta *proxy.OutboundHandlerMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
|
||||||
defer ray.OutboundInput().Release()
|
defer ray.OutboundInput().Release()
|
||||||
defer ray.OutboundOutput().Close()
|
defer ray.OutboundOutput().Close()
|
||||||
|
|
||||||
var rec *Receiver
|
var rec *protocol.ServerSpec
|
||||||
var conn internet.Connection
|
var conn internet.Connection
|
||||||
|
|
||||||
err := retry.Timed(5, 100).On(func() error {
|
err := retry.Timed(5, 100).On(func() error {
|
||||||
rec = this.receiverManager.PickReceiver()
|
rec = this.serverPicker.PickServer()
|
||||||
rawConn, err := internet.Dial(this.meta.Address, rec.Destination, this.meta.StreamSettings)
|
rawConn, err := internet.Dial(this.meta.Address, rec.Destination(), this.meta.StreamSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -77,7 +78,7 @@ func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *al
|
||||||
session := encoding.NewClientSession(protocol.DefaultIDHash)
|
session := encoding.NewClientSession(protocol.DefaultIDHash)
|
||||||
|
|
||||||
go this.handleRequest(session, conn, request, payload, input, &requestFinish)
|
go this.handleRequest(session, conn, request, payload, input, &requestFinish)
|
||||||
go this.handleResponse(session, conn, request, rec.Destination, output, &responseFinish)
|
go this.handleResponse(session, conn, request, rec.Destination(), output, &responseFinish)
|
||||||
|
|
||||||
requestFinish.Lock()
|
requestFinish.Lock()
|
||||||
responseFinish.Lock()
|
responseFinish.Lock()
|
||||||
|
@ -163,9 +164,14 @@ func (this *Factory) StreamCapability() internet.StreamConnectionType {
|
||||||
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||||
vOutConfig := rawConfig.(*Config)
|
vOutConfig := rawConfig.(*Config)
|
||||||
|
|
||||||
|
serverList := protocol.NewServerList()
|
||||||
|
for _, rec := range vOutConfig.Receivers {
|
||||||
|
serverList.AddServer(rec)
|
||||||
|
}
|
||||||
handler := &VMessOutboundHandler{
|
handler := &VMessOutboundHandler{
|
||||||
receiverManager: NewReceiverManager(vOutConfig.Receivers),
|
serverList: serverList,
|
||||||
meta: meta,
|
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
|
||||||
|
meta: meta,
|
||||||
}
|
}
|
||||||
|
|
||||||
return handler, nil
|
return handler, nil
|
||||||
|
|
|
@ -1,136 +0,0 @@
|
||||||
package outbound
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/common/dice"
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
||||||
"github.com/v2ray/v2ray-core/common/protocol"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Receiver struct {
|
|
||||||
sync.RWMutex
|
|
||||||
Destination v2net.Destination
|
|
||||||
Accounts []*protocol.User
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewReceiver(dest v2net.Destination, users ...*protocol.User) *Receiver {
|
|
||||||
return &Receiver{
|
|
||||||
Destination: dest,
|
|
||||||
Accounts: users,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Receiver) HasUser(user *protocol.User) bool {
|
|
||||||
this.RLock()
|
|
||||||
defer this.RUnlock()
|
|
||||||
account := user.Account.(*protocol.VMessAccount)
|
|
||||||
for _, u := range this.Accounts {
|
|
||||||
// TODO: handle AlterIds difference.
|
|
||||||
uAccount := u.Account.(*protocol.VMessAccount)
|
|
||||||
if uAccount.ID.Equals(account.ID) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Receiver) AddUser(user *protocol.User) {
|
|
||||||
if this.HasUser(user) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.Lock()
|
|
||||||
this.Accounts = append(this.Accounts, user)
|
|
||||||
this.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Receiver) PickUser() *protocol.User {
|
|
||||||
return this.Accounts[dice.Roll(len(this.Accounts))]
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExpiringReceiver struct {
|
|
||||||
*Receiver
|
|
||||||
until time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ExpiringReceiver) Expired() bool {
|
|
||||||
return this.until.Before(time.Now())
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReceiverManager struct {
|
|
||||||
receivers []*Receiver
|
|
||||||
detours []*ExpiringReceiver
|
|
||||||
detourAccess sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewReceiverManager(receivers []*Receiver) *ReceiverManager {
|
|
||||||
return &ReceiverManager{
|
|
||||||
receivers: receivers,
|
|
||||||
detours: make([]*ExpiringReceiver, 0, 16),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ReceiverManager) AddDetour(rec *Receiver, availableMin byte) {
|
|
||||||
if availableMin < 2 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.detourAccess.RLock()
|
|
||||||
destExists := false
|
|
||||||
for _, r := range this.detours {
|
|
||||||
if r.Destination == rec.Destination {
|
|
||||||
destExists = true
|
|
||||||
// Destination exists, add new user if necessary
|
|
||||||
for _, u := range rec.Accounts {
|
|
||||||
r.AddUser(u)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.detourAccess.RUnlock()
|
|
||||||
if !destExists {
|
|
||||||
expRec := &ExpiringReceiver{
|
|
||||||
Receiver: rec,
|
|
||||||
until: time.Now().Add(time.Duration(availableMin-1) * time.Minute),
|
|
||||||
}
|
|
||||||
this.detourAccess.Lock()
|
|
||||||
this.detours = append(this.detours, expRec)
|
|
||||||
this.detourAccess.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ReceiverManager) pickDetour() *Receiver {
|
|
||||||
if len(this.detours) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
this.detourAccess.RLock()
|
|
||||||
idx := dice.Roll(len(this.detours))
|
|
||||||
rec := this.detours[idx]
|
|
||||||
this.detourAccess.RUnlock()
|
|
||||||
|
|
||||||
if rec.Expired() {
|
|
||||||
this.detourAccess.Lock()
|
|
||||||
detourLen := len(this.detours)
|
|
||||||
if detourLen > idx && this.detours[idx].Expired() {
|
|
||||||
this.detours[idx] = this.detours[detourLen-1]
|
|
||||||
this.detours = this.detours[:detourLen-1]
|
|
||||||
}
|
|
||||||
this.detourAccess.Unlock()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return rec.Receiver
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ReceiverManager) pickStdReceiver() *Receiver {
|
|
||||||
return this.receivers[dice.Roll(len(this.receivers))]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ReceiverManager) PickReceiver() *Receiver {
|
|
||||||
rec := this.pickDetour()
|
|
||||||
if rec == nil {
|
|
||||||
rec = this.pickStdReceiver()
|
|
||||||
}
|
|
||||||
return rec
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
// +build json
|
|
||||||
|
|
||||||
package outbound
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
||||||
"github.com/v2ray/v2ray-core/common/protocol"
|
|
||||||
"github.com/v2ray/v2ray-core/common/serial"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (this *Receiver) UnmarshalJSON(data []byte) error {
|
|
||||||
type RawConfigTarget struct {
|
|
||||||
Address *v2net.AddressJson `json:"address"`
|
|
||||||
Port v2net.Port `json:"port"`
|
|
||||||
Users []*protocol.User `json:"users"`
|
|
||||||
}
|
|
||||||
var rawConfig RawConfigTarget
|
|
||||||
if err := json.Unmarshal(data, &rawConfig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(rawConfig.Users) == 0 {
|
|
||||||
log.Error("VMess: 0 user configured for VMess outbound.")
|
|
||||||
return internal.ErrBadConfiguration
|
|
||||||
}
|
|
||||||
this.Accounts = rawConfig.Users
|
|
||||||
if rawConfig.Address == nil {
|
|
||||||
log.Error("VMess: Address is not set in VMess outbound config.")
|
|
||||||
return internal.ErrBadConfiguration
|
|
||||||
}
|
|
||||||
if rawConfig.Address.Address.String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) {
|
|
||||||
rawConfig.Address.Address = v2net.IPAddress(serial.Uint32ToBytes(2891346854, nil))
|
|
||||||
}
|
|
||||||
this.Destination = v2net.TCPDestination(rawConfig.Address.Address, rawConfig.Port)
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
// +build json
|
|
||||||
|
|
||||||
package outbound_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/common/protocol"
|
|
||||||
. "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
|
||||||
"github.com/v2ray/v2ray-core/testing/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestConfigTargetParsing(t *testing.T) {
|
|
||||||
assert := assert.On(t)
|
|
||||||
|
|
||||||
rawJson := `{
|
|
||||||
"address": "127.0.0.1",
|
|
||||||
"port": 80,
|
|
||||||
"users": [
|
|
||||||
{
|
|
||||||
"id": "e641f5ad-9397-41e3-bf1a-e8740dfed019",
|
|
||||||
"email": "love@v2ray.com",
|
|
||||||
"level": 255
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}`
|
|
||||||
|
|
||||||
receiver := new(Receiver)
|
|
||||||
err := json.Unmarshal([]byte(rawJson), &receiver)
|
|
||||||
assert.Error(err).IsNil()
|
|
||||||
assert.Destination(receiver.Destination).EqualsString("tcp:127.0.0.1:80")
|
|
||||||
assert.Int(len(receiver.Accounts)).Equals(1)
|
|
||||||
|
|
||||||
account := receiver.Accounts[0].Account.(*protocol.VMessAccount)
|
|
||||||
assert.String(account.ID.String()).Equals("e641f5ad-9397-41e3-bf1a-e8740dfed019")
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package outbound_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
||||||
"github.com/v2ray/v2ray-core/common/protocol"
|
|
||||||
"github.com/v2ray/v2ray-core/common/uuid"
|
|
||||||
. "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
|
||||||
"github.com/v2ray/v2ray-core/testing/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestReceiverUser(t *testing.T) {
|
|
||||||
assert := assert.On(t)
|
|
||||||
|
|
||||||
id := protocol.NewID(uuid.New())
|
|
||||||
alters := protocol.NewAlterIDs(id, 100)
|
|
||||||
account := &protocol.VMessAccount{
|
|
||||||
ID: id,
|
|
||||||
AlterIDs: alters,
|
|
||||||
}
|
|
||||||
user := protocol.NewUser(account, protocol.UserLevel(0), "")
|
|
||||||
rec := NewReceiver(v2net.TCPDestination(v2net.DomainAddress("v2ray.com"), 80), user)
|
|
||||||
assert.Bool(rec.HasUser(user)).IsTrue()
|
|
||||||
assert.Int(len(rec.Accounts)).Equals(1)
|
|
||||||
|
|
||||||
id2 := protocol.NewID(uuid.New())
|
|
||||||
alters2 := protocol.NewAlterIDs(id2, 100)
|
|
||||||
account2 := &protocol.VMessAccount{
|
|
||||||
ID: id2,
|
|
||||||
AlterIDs: alters2,
|
|
||||||
}
|
|
||||||
user2 := protocol.NewUser(account2, protocol.UserLevel(0), "")
|
|
||||||
assert.Bool(rec.HasUser(user2)).IsFalse()
|
|
||||||
|
|
||||||
rec.AddUser(user2)
|
|
||||||
assert.Bool(rec.HasUser(user2)).IsTrue()
|
|
||||||
assert.Int(len(rec.Accounts)).Equals(2)
|
|
||||||
}
|
|
Loading…
Reference in New Issue