mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-02-20 23:47:21 -05:00
massive refactoring against json config parsing
This commit is contained in:
parent
f87ab4713c
commit
e5fa96f814
@ -1,4 +1,4 @@
|
|||||||
package blackhole
|
package blackhole
|
||||||
|
|
||||||
type Config interface {
|
type Config struct {
|
||||||
}
|
}
|
||||||
|
14
proxy/blackhole/config_json.go
Normal file
14
proxy/blackhole/config_json.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package blackhole
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config.RegisterOutboundConnectionConfig("blackhole",
|
||||||
|
func(data []byte) (interface{}, error) {
|
||||||
|
return new(Config), nil
|
||||||
|
})
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BlackHoleConfig struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
config.RegisterOutboundConnectionConfig("blackhole", json.JsonConfigLoader(func() interface{} {
|
|
||||||
return new(BlackHoleConfig)
|
|
||||||
}))
|
|
||||||
}
|
|
@ -4,9 +4,9 @@ import (
|
|||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config interface {
|
type Config struct {
|
||||||
Address() v2net.Address
|
Address v2net.Address
|
||||||
Port() v2net.Port
|
Port v2net.Port
|
||||||
Network() v2net.NetworkList
|
Network v2net.NetworkList
|
||||||
Timeout() int
|
Timeout int
|
||||||
}
|
}
|
||||||
|
33
proxy/dokodemo/config_json.go
Normal file
33
proxy/dokodemo/config_json.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package dokodemo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
v2netjson "github.com/v2ray/v2ray-core/common/net/json"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config.RegisterInboundConnectionConfig("dokodemo-door",
|
||||||
|
func(data []byte) (interface{}, error) {
|
||||||
|
type DokodemoConfig struct {
|
||||||
|
Host *v2netjson.Host `json:"address"`
|
||||||
|
PortValue v2net.Port `json:"port"`
|
||||||
|
NetworkList *v2netjson.NetworkList `json:"network"`
|
||||||
|
TimeoutValue int `json:"timeout"`
|
||||||
|
}
|
||||||
|
rawConfig := new(DokodemoConfig)
|
||||||
|
if err := json.Unmarshal(data, rawConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Config{
|
||||||
|
Address: rawConfig.Host.Address(),
|
||||||
|
Port: rawConfig.PortValue,
|
||||||
|
Network: rawConfig.NetworkList,
|
||||||
|
Timeout: rawConfig.TimeoutValue,
|
||||||
|
}, nil
|
||||||
|
})
|
||||||
|
}
|
@ -15,7 +15,7 @@ import (
|
|||||||
type DokodemoDoor struct {
|
type DokodemoDoor struct {
|
||||||
tcpMutex sync.RWMutex
|
tcpMutex sync.RWMutex
|
||||||
udpMutex sync.RWMutex
|
udpMutex sync.RWMutex
|
||||||
config Config
|
config *Config
|
||||||
accepting bool
|
accepting bool
|
||||||
address v2net.Address
|
address v2net.Address
|
||||||
port v2net.Port
|
port v2net.Port
|
||||||
@ -24,12 +24,12 @@ type DokodemoDoor struct {
|
|||||||
udpConn *net.UDPConn
|
udpConn *net.UDPConn
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDokodemoDoor(space app.Space, config Config) *DokodemoDoor {
|
func NewDokodemoDoor(space app.Space, config *Config) *DokodemoDoor {
|
||||||
return &DokodemoDoor{
|
return &DokodemoDoor{
|
||||||
config: config,
|
config: config,
|
||||||
space: space,
|
space: space,
|
||||||
address: config.Address(),
|
address: config.Address,
|
||||||
port: config.Port(),
|
port: config.Port,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,13 +52,13 @@ func (this *DokodemoDoor) Close() {
|
|||||||
func (this *DokodemoDoor) Listen(port v2net.Port) error {
|
func (this *DokodemoDoor) Listen(port v2net.Port) error {
|
||||||
this.accepting = true
|
this.accepting = true
|
||||||
|
|
||||||
if this.config.Network().HasNetwork(v2net.TCPNetwork) {
|
if this.config.Network.HasNetwork(v2net.TCPNetwork) {
|
||||||
err := this.ListenTCP(port)
|
err := this.ListenTCP(port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if this.config.Network().HasNetwork(v2net.UDPNetwork) {
|
if this.config.Network.HasNetwork(v2net.UDPNetwork) {
|
||||||
err := this.ListenUDP(port)
|
err := this.ListenUDP(port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -163,7 +163,7 @@ func (this *DokodemoDoor) HandleTCPConnection(conn *net.TCPConn) {
|
|||||||
inputFinish.Lock()
|
inputFinish.Lock()
|
||||||
outputFinish.Lock()
|
outputFinish.Lock()
|
||||||
|
|
||||||
reader := v2net.NewTimeOutReader(this.config.Timeout(), conn)
|
reader := v2net.NewTimeOutReader(this.config.Timeout, conn)
|
||||||
go dumpInput(reader, ray.InboundInput(), &inputFinish)
|
go dumpInput(reader, ray.InboundInput(), &inputFinish)
|
||||||
go dumpOutput(conn, ray.InboundOutput(), &outputFinish)
|
go dumpOutput(conn, ray.InboundOutput(), &outputFinish)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
internal.MustRegisterInboundConnectionHandlerCreator("dokodemo-door",
|
internal.MustRegisterInboundConnectionHandlerCreator("dokodemo-door",
|
||||||
func(space app.Space, rawConfig interface{}) (proxy.InboundConnectionHandler, error) {
|
func(space app.Space, rawConfig interface{}) (proxy.InboundConnectionHandler, error) {
|
||||||
config := rawConfig.(Config)
|
config := rawConfig.(*Config)
|
||||||
return NewDokodemoDoor(space, config), nil
|
return NewDokodemoDoor(space, config), nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package dokodemo
|
package dokodemo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
|
v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/dokodemo/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/freedom"
|
_ "github.com/v2ray/v2ray-core/proxy/freedom"
|
||||||
"github.com/v2ray/v2ray-core/shell/point"
|
"github.com/v2ray/v2ray-core/shell/point"
|
||||||
"github.com/v2ray/v2ray-core/shell/point/testing/mocks"
|
"github.com/v2ray/v2ray-core/shell/point/testing/mocks"
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
||||||
v2netjson "github.com/v2ray/v2ray-core/common/net/json"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DokodemoConfig struct {
|
|
||||||
Host *v2netjson.Host `json:"address"`
|
|
||||||
PortValue v2net.Port `json:"port"`
|
|
||||||
NetworkList *v2netjson.NetworkList `json:"network"`
|
|
||||||
TimeoutValue int `json:"timeout"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *DokodemoConfig) Address() v2net.Address {
|
|
||||||
return this.Host.Address()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *DokodemoConfig) Port() v2net.Port {
|
|
||||||
return this.PortValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *DokodemoConfig) Network() v2net.NetworkList {
|
|
||||||
return this.NetworkList
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *DokodemoConfig) Timeout() int {
|
|
||||||
return this.TimeoutValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
config.RegisterInboundConnectionConfig("dokodemo-door", json.JsonConfigLoader(func() interface{} {
|
|
||||||
return new(DokodemoConfig)
|
|
||||||
}))
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package freedom
|
package freedom
|
||||||
|
|
||||||
type Config interface {
|
type Config struct {
|
||||||
}
|
}
|
||||||
|
14
proxy/freedom/config_json.go
Normal file
14
proxy/freedom/config_json.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package freedom
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config.RegisterOutboundConnectionConfig("freedom",
|
||||||
|
func(data []byte) (interface{}, error) {
|
||||||
|
return new(Config), nil
|
||||||
|
})
|
||||||
|
}
|
@ -14,7 +14,6 @@ import (
|
|||||||
v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
|
v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
|
||||||
v2proxy "github.com/v2ray/v2ray-core/proxy"
|
v2proxy "github.com/v2ray/v2ray-core/proxy"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/socks"
|
_ "github.com/v2ray/v2ray-core/proxy/socks"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/socks/json"
|
|
||||||
proxytesting "github.com/v2ray/v2ray-core/proxy/testing"
|
proxytesting "github.com/v2ray/v2ray-core/proxy/testing"
|
||||||
proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks"
|
proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks"
|
||||||
"github.com/v2ray/v2ray-core/shell/point"
|
"github.com/v2ray/v2ray-core/shell/point"
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FreedomConfiguration struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
config.RegisterOutboundConnectionConfig("freedom", json.JsonConfigLoader(func() interface{} {
|
|
||||||
return &FreedomConfiguration{}
|
|
||||||
}))
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
type Config interface {
|
type Config struct {
|
||||||
}
|
}
|
||||||
|
14
proxy/http/config_json.go
Normal file
14
proxy/http/config_json.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config.RegisterInboundConnectionConfig("http",
|
||||||
|
func(data []byte) (interface{}, error) {
|
||||||
|
return new(Config), nil
|
||||||
|
})
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
type HttpProxyConfig struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
config.RegisterInboundConnectionConfig("http", json.JsonConfigLoader(func() interface{} {
|
|
||||||
return new(HttpProxyConfig)
|
|
||||||
}))
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func JsonConfigLoader(newConfig func() interface{}) func(data []byte) (interface{}, error) {
|
|
||||||
return func(data []byte) (interface{}, error) {
|
|
||||||
obj := newConfig()
|
|
||||||
log.Debug("Unmarshalling JSON: %s", string(data))
|
|
||||||
err := json.Unmarshal(data, obj)
|
|
||||||
return obj, err
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +1,28 @@
|
|||||||
package socks
|
package socks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config interface {
|
const (
|
||||||
IsNoAuth() bool
|
AuthTypeNoAuth = byte(0)
|
||||||
IsPassword() bool
|
AuthTypePassword = byte(1)
|
||||||
HasAccount(username, password string) bool
|
)
|
||||||
IP() net.IP
|
|
||||||
UDPEnabled() bool
|
type Config struct {
|
||||||
|
AuthType byte
|
||||||
|
Accounts map[string]string
|
||||||
|
Address v2net.Address
|
||||||
|
UDPEnabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Config) HasAccount(username, password string) bool {
|
||||||
|
if this.Accounts == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
storedPassed, found := this.Accounts[username]
|
||||||
|
if !found {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return storedPassed == password
|
||||||
}
|
}
|
||||||
|
64
proxy/socks/config_json.go
Normal file
64
proxy/socks/config_json.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package socks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
v2netjson "github.com/v2ray/v2ray-core/common/net/json"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/internal"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AuthMethodNoAuth = "noauth"
|
||||||
|
AuthMethodUserPass = "password"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config.RegisterInboundConnectionConfig("socks",
|
||||||
|
func(data []byte) (interface{}, error) {
|
||||||
|
type SocksAccount struct {
|
||||||
|
Username string `json:"user"`
|
||||||
|
Password string `json:"pass"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SocksConfig struct {
|
||||||
|
AuthMethod string `json:"auth"`
|
||||||
|
Accounts []*SocksAccount `json:"accounts"`
|
||||||
|
UDP bool `json:"udp"`
|
||||||
|
Host *v2netjson.Host `json:"ip"`
|
||||||
|
}
|
||||||
|
|
||||||
|
rawConfig := new(SocksConfig)
|
||||||
|
if err := json.Unmarshal(data, rawConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
socksConfig := new(Config)
|
||||||
|
if rawConfig.AuthMethod == AuthMethodNoAuth {
|
||||||
|
socksConfig.AuthType = AuthTypeNoAuth
|
||||||
|
} else if rawConfig.AuthMethod == AuthMethodUserPass {
|
||||||
|
socksConfig.AuthType = AuthTypePassword
|
||||||
|
} else {
|
||||||
|
log.Error("Socks: Unknown auth method: %s", rawConfig.AuthMethod)
|
||||||
|
return nil, internal.ErrorBadConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(rawConfig.Accounts) > 0 {
|
||||||
|
socksConfig.Accounts = make(map[string]string, len(rawConfig.Accounts))
|
||||||
|
for _, account := range rawConfig.Accounts {
|
||||||
|
socksConfig.Accounts[account.Username] = account.Password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
socksConfig.UDPEnabled = rawConfig.UDP
|
||||||
|
if rawConfig.Host != nil {
|
||||||
|
socksConfig.Address = rawConfig.Host.Address()
|
||||||
|
} else {
|
||||||
|
socksConfig.Address = v2net.IPAddress([]byte{127, 0, 0, 1})
|
||||||
|
}
|
||||||
|
return socksConfig, nil
|
||||||
|
})
|
||||||
|
}
|
22
proxy/socks/config_json_test.go
Normal file
22
proxy/socks/config_json_test.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package socks_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/socks"
|
||||||
|
v2testing "github.com/v2ray/v2ray-core/testing"
|
||||||
|
"github.com/v2ray/v2ray-core/testing/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDefaultIPAddress(t *testing.T) {
|
||||||
|
v2testing.Current(t)
|
||||||
|
|
||||||
|
socksConfig, err := config.CreateInboundConnectionConfig("socks", []byte(`{
|
||||||
|
"auth": "noauth"
|
||||||
|
}`))
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
assert.String(socksConfig.(*socks.Config).Address).Equals("127.0.0.1")
|
||||||
|
}
|
@ -1,93 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"net"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
|
||||||
jsonconfig "github.com/v2ray/v2ray-core/proxy/internal/config/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
AuthMethodNoAuth = "noauth"
|
|
||||||
AuthMethodUserPass = "password"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SocksAccount struct {
|
|
||||||
Username string `json:"user"`
|
|
||||||
Password string `json:"pass"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SocksAccountMap map[string]string
|
|
||||||
|
|
||||||
func (this *SocksAccountMap) UnmarshalJSON(data []byte) error {
|
|
||||||
var accounts []SocksAccount
|
|
||||||
err := json.Unmarshal(data, &accounts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*this = make(map[string]string)
|
|
||||||
for _, account := range accounts {
|
|
||||||
(*this)[account.Username] = account.Password
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *SocksAccountMap) HasAccount(user, pass string) bool {
|
|
||||||
if actualPass, found := (*this)[user]; found {
|
|
||||||
return actualPass == pass
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type IPAddress net.IP
|
|
||||||
|
|
||||||
func (this *IPAddress) UnmarshalJSON(data []byte) error {
|
|
||||||
var ipStr string
|
|
||||||
err := json.Unmarshal(data, &ipStr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ip := net.ParseIP(ipStr)
|
|
||||||
if ip == nil {
|
|
||||||
return errors.New("Unknown IP format: " + ipStr)
|
|
||||||
}
|
|
||||||
*this = IPAddress(ip)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type SocksConfig struct {
|
|
||||||
AuthMethod string `json:"auth"`
|
|
||||||
Accounts SocksAccountMap `json:"accounts"`
|
|
||||||
UDP bool `json:"udp"`
|
|
||||||
HostIP IPAddress `json:"ip"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *SocksConfig) IsNoAuth() bool {
|
|
||||||
return sc.AuthMethod == AuthMethodNoAuth
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *SocksConfig) IsPassword() bool {
|
|
||||||
return sc.AuthMethod == AuthMethodUserPass
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *SocksConfig) HasAccount(user, pass string) bool {
|
|
||||||
return sc.Accounts.HasAccount(user, pass)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sc *SocksConfig) IP() net.IP {
|
|
||||||
return net.IP(sc.HostIP)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *SocksConfig) UDPEnabled() bool {
|
|
||||||
return this.UDP
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
config.RegisterInboundConnectionConfig("socks", jsonconfig.JsonConfigLoader(func() interface{} {
|
|
||||||
return &SocksConfig{
|
|
||||||
HostIP: IPAddress(net.IPv4(127, 0, 0, 1)),
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
|
||||||
v2testing "github.com/v2ray/v2ray-core/testing"
|
|
||||||
"github.com/v2ray/v2ray-core/testing/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAccountMapParsing(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
var accountMap SocksAccountMap
|
|
||||||
err := json.Unmarshal([]byte("[{\"user\": \"a\", \"pass\":\"b\"}, {\"user\": \"c\", \"pass\":\"d\"}]"), &accountMap)
|
|
||||||
assert.Error(err).IsNil()
|
|
||||||
|
|
||||||
assert.Bool(accountMap.HasAccount("a", "b")).IsTrue()
|
|
||||||
assert.Bool(accountMap.HasAccount("a", "c")).IsFalse()
|
|
||||||
assert.Bool(accountMap.HasAccount("c", "d")).IsTrue()
|
|
||||||
assert.Bool(accountMap.HasAccount("e", "d")).IsFalse()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDefaultIPAddress(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
socksConfig, err := config.CreateInboundConnectionConfig("socks", []byte(`{}`))
|
|
||||||
assert.Error(err).IsNil()
|
|
||||||
assert.String(socksConfig.(*SocksConfig).IP()).Equals("127.0.0.1")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIPAddressParsing(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
var ipAddress IPAddress
|
|
||||||
err := json.Unmarshal([]byte("\"1.2.3.4\""), &ipAddress)
|
|
||||||
assert.Error(err).IsNil()
|
|
||||||
assert.String(net.IP(ipAddress)).Equals("1.2.3.4")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNoAuthConfig(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
var config SocksConfig
|
|
||||||
err := json.Unmarshal([]byte("{\"auth\":\"noauth\", \"ip\":\"8.8.8.8\"}"), &config)
|
|
||||||
assert.Error(err).IsNil()
|
|
||||||
assert.Bool(config.IsNoAuth()).IsTrue()
|
|
||||||
assert.Bool(config.IsPassword()).IsFalse()
|
|
||||||
assert.String(config.IP()).Equals("8.8.8.8")
|
|
||||||
assert.Bool(config.UDPEnabled()).IsFalse()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUserPassConfig(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
var config SocksConfig
|
|
||||||
err := json.Unmarshal([]byte("{\"auth\":\"password\", \"accounts\":[{\"user\":\"x\", \"pass\":\"y\"}], \"udp\":true}"), &config)
|
|
||||||
assert.Error(err).IsNil()
|
|
||||||
assert.Bool(config.IsNoAuth()).IsFalse()
|
|
||||||
assert.Bool(config.IsPassword()).IsTrue()
|
|
||||||
assert.Bool(config.HasAccount("x", "y")).IsTrue()
|
|
||||||
assert.Bool(config.UDPEnabled()).IsTrue()
|
|
||||||
}
|
|
@ -27,13 +27,13 @@ type SocksServer struct {
|
|||||||
udpMutex sync.RWMutex
|
udpMutex sync.RWMutex
|
||||||
accepting bool
|
accepting bool
|
||||||
space app.Space
|
space app.Space
|
||||||
config Config
|
config *Config
|
||||||
tcpListener *net.TCPListener
|
tcpListener *net.TCPListener
|
||||||
udpConn *net.UDPConn
|
udpConn *net.UDPConn
|
||||||
udpAddress v2net.Destination
|
udpAddress v2net.Destination
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSocksServer(space app.Space, config Config) *SocksServer {
|
func NewSocksServer(space app.Space, config *Config) *SocksServer {
|
||||||
return &SocksServer{
|
return &SocksServer{
|
||||||
space: space,
|
space: space,
|
||||||
config: config,
|
config: config,
|
||||||
@ -71,7 +71,7 @@ func (this *SocksServer) Listen(port v2net.Port) error {
|
|||||||
this.tcpListener = listener
|
this.tcpListener = listener
|
||||||
this.tcpMutex.Unlock()
|
this.tcpMutex.Unlock()
|
||||||
go this.AcceptConnections()
|
go this.AcceptConnections()
|
||||||
if this.config.UDPEnabled() {
|
if this.config.UDPEnabled {
|
||||||
this.ListenUDP(port)
|
this.ListenUDP(port)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -116,7 +116,7 @@ func (this *SocksServer) HandleConnection(connection *net.TCPConn) error {
|
|||||||
|
|
||||||
func (this *SocksServer) handleSocks5(reader *v2net.TimeOutReader, writer io.Writer, auth protocol.Socks5AuthenticationRequest) error {
|
func (this *SocksServer) handleSocks5(reader *v2net.TimeOutReader, writer io.Writer, auth protocol.Socks5AuthenticationRequest) error {
|
||||||
expectedAuthMethod := protocol.AuthNotRequired
|
expectedAuthMethod := protocol.AuthNotRequired
|
||||||
if this.config.IsPassword() {
|
if this.config.AuthType == AuthTypePassword {
|
||||||
expectedAuthMethod = protocol.AuthUserPass
|
expectedAuthMethod = protocol.AuthUserPass
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ func (this *SocksServer) handleSocks5(reader *v2net.TimeOutReader, writer io.Wri
|
|||||||
log.Error("Socks failed to write authentication: %v", err)
|
log.Error("Socks failed to write authentication: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if this.config.IsPassword() {
|
if this.config.AuthType == AuthTypePassword {
|
||||||
upRequest, err := protocol.ReadUserPassRequest(reader)
|
upRequest, err := protocol.ReadUserPassRequest(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Socks failed to read username and password: %v", err)
|
log.Error("Socks failed to read username and password: %v", err)
|
||||||
@ -165,7 +165,7 @@ func (this *SocksServer) handleSocks5(reader *v2net.TimeOutReader, writer io.Wri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if request.Command == protocol.CmdUdpAssociate && this.config.UDPEnabled() {
|
if request.Command == protocol.CmdUdpAssociate && this.config.UDPEnabled {
|
||||||
return this.handleUDP(reader, writer)
|
return this.handleUDP(reader, writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package socks
|
package socks_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core/app"
|
"github.com/v2ray/v2ray-core/app"
|
||||||
v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
|
v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
|
||||||
v2proxy "github.com/v2ray/v2ray-core/proxy"
|
v2proxy "github.com/v2ray/v2ray-core/proxy"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/socks/json"
|
|
||||||
proxytesting "github.com/v2ray/v2ray-core/proxy/testing"
|
proxytesting "github.com/v2ray/v2ray-core/proxy/testing"
|
||||||
proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks"
|
proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks"
|
||||||
"github.com/v2ray/v2ray-core/shell/point"
|
"github.com/v2ray/v2ray-core/shell/point"
|
||||||
|
@ -9,6 +9,6 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
internal.MustRegisterInboundConnectionHandlerCreator("socks",
|
internal.MustRegisterInboundConnectionHandlerCreator("socks",
|
||||||
func(space app.Space, rawConfig interface{}) (proxy.InboundConnectionHandler, error) {
|
func(space app.Space, rawConfig interface{}) (proxy.InboundConnectionHandler, error) {
|
||||||
return NewSocksServer(space, rawConfig.(Config)), nil
|
return NewSocksServer(space, rawConfig.(*Config)), nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ func (this *SocksServer) ListenUDP(port v2net.Port) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.udpMutex.Lock()
|
this.udpMutex.Lock()
|
||||||
this.udpAddress = v2net.UDPDestination(v2net.IPAddress(this.config.IP()), port)
|
this.udpAddress = v2net.UDPDestination(this.config.Address, port)
|
||||||
this.udpConn = conn
|
this.udpConn = conn
|
||||||
this.udpMutex.Unlock()
|
this.udpMutex.Unlock()
|
||||||
|
|
||||||
|
@ -4,6 +4,6 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core/proxy/vmess"
|
"github.com/v2ray/v2ray-core/proxy/vmess"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config interface {
|
type Config struct {
|
||||||
AllowedUsers() []vmess.User
|
AllowedUsers []*vmess.User
|
||||||
}
|
}
|
||||||
|
26
proxy/vmess/inbound/config_json.go
Normal file
26
proxy/vmess/inbound/config_json.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package inbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/vmess"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
config.RegisterInboundConnectionConfig("vmess",
|
||||||
|
func(data []byte) (interface{}, error) {
|
||||||
|
type JsonConfig struct {
|
||||||
|
Users []*vmess.User `json:"clients"`
|
||||||
|
}
|
||||||
|
jsonConfig := new(JsonConfig)
|
||||||
|
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Config{
|
||||||
|
AllowedUsers: jsonConfig.Users,
|
||||||
|
}, nil
|
||||||
|
})
|
||||||
|
}
|
@ -109,7 +109,7 @@ func (this *VMessInboundHandler) HandleConnection(connection *net.TCPConn) error
|
|||||||
readFinish.Lock()
|
readFinish.Lock()
|
||||||
writeFinish.Lock()
|
writeFinish.Lock()
|
||||||
|
|
||||||
userSettings := vmess.GetUserSettings(request.User.Level())
|
userSettings := vmess.GetUserSettings(request.User.Level)
|
||||||
connReader.SetTimeOut(userSettings.PayloadReadTimeout)
|
connReader.SetTimeOut(userSettings.PayloadReadTimeout)
|
||||||
go handleInput(request, connReader, input, &readFinish)
|
go handleInput(request, connReader, input, &readFinish)
|
||||||
|
|
||||||
@ -167,10 +167,10 @@ func handleOutput(request *protocol.VMessRequest, writer io.Writer, output <-cha
|
|||||||
func init() {
|
func init() {
|
||||||
internal.MustRegisterInboundConnectionHandlerCreator("vmess",
|
internal.MustRegisterInboundConnectionHandlerCreator("vmess",
|
||||||
func(space app.Space, rawConfig interface{}) (proxy.InboundConnectionHandler, error) {
|
func(space app.Space, rawConfig interface{}) (proxy.InboundConnectionHandler, error) {
|
||||||
config := rawConfig.(Config)
|
config := rawConfig.(*Config)
|
||||||
|
|
||||||
allowedClients := protocol.NewTimedUserSet()
|
allowedClients := protocol.NewTimedUserSet()
|
||||||
for _, user := range config.AllowedUsers() {
|
for _, user := range config.AllowedUsers {
|
||||||
allowedClients.AddUser(user)
|
allowedClients.AddUser(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal/config/json"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/vmess"
|
|
||||||
vmessjson "github.com/v2ray/v2ray-core/proxy/vmess/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Inbound struct {
|
|
||||||
AllowedClients []*vmessjson.ConfigUser `json:"clients"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Inbound) AllowedUsers() []vmess.User {
|
|
||||||
users := make([]vmess.User, 0, len(c.AllowedClients))
|
|
||||||
for _, rawUser := range c.AllowedClients {
|
|
||||||
users = append(users, rawUser)
|
|
||||||
}
|
|
||||||
return users
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
config.RegisterInboundConnectionConfig("vmess", json.JsonConfigLoader(func() interface{} {
|
|
||||||
return new(Inbound)
|
|
||||||
}))
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"math/rand"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/common/uuid"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/vmess"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ConfigUser is an user account in VMess configuration.
|
|
||||||
type ConfigUser struct {
|
|
||||||
Id *vmess.ID
|
|
||||||
Email string
|
|
||||||
LevelValue vmess.UserLevel
|
|
||||||
AlterIds []*vmess.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *ConfigUser) UnmarshalJSON(data []byte) error {
|
|
||||||
type rawUser struct {
|
|
||||||
IdString string `json:"id"`
|
|
||||||
EmailString string `json:"email"`
|
|
||||||
LevelInt int `json:"level"`
|
|
||||||
AlterIdCount int `json:"alterId"`
|
|
||||||
}
|
|
||||||
var rawUserValue rawUser
|
|
||||||
if err := json.Unmarshal(data, &rawUserValue); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
id, err := uuid.ParseString(rawUserValue.IdString)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
u.Id = vmess.NewID(id)
|
|
||||||
u.Email = rawUserValue.EmailString
|
|
||||||
u.LevelValue = vmess.UserLevel(rawUserValue.LevelInt)
|
|
||||||
|
|
||||||
if rawUserValue.AlterIdCount > 0 {
|
|
||||||
prevId := u.Id.UUID()
|
|
||||||
// TODO: check duplicate
|
|
||||||
u.AlterIds = make([]*vmess.ID, rawUserValue.AlterIdCount)
|
|
||||||
for idx, _ := range u.AlterIds {
|
|
||||||
newid := prevId.Next()
|
|
||||||
u.AlterIds[idx] = vmess.NewID(newid)
|
|
||||||
prevId = newid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *ConfigUser) ID() *vmess.ID {
|
|
||||||
return u.Id
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ConfigUser) Level() vmess.UserLevel {
|
|
||||||
return this.LevelValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ConfigUser) AlterIDs() []*vmess.ID {
|
|
||||||
return this.AlterIds
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *ConfigUser) AnyValidID() *vmess.ID {
|
|
||||||
if len(this.AlterIds) == 0 {
|
|
||||||
return this.ID()
|
|
||||||
}
|
|
||||||
if len(this.AlterIds) == 1 {
|
|
||||||
return this.AlterIds[0]
|
|
||||||
}
|
|
||||||
idIdx := rand.Intn(len(this.AlterIds))
|
|
||||||
return this.AlterIds[idIdx]
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
package outbound
|
package outbound
|
||||||
|
|
||||||
type Config interface {
|
type Config struct {
|
||||||
Receivers() []*Receiver
|
Receivers []*Receiver
|
||||||
}
|
}
|
||||||
|
39
proxy/vmess/outbound/config_json.go
Normal file
39
proxy/vmess/outbound/config_json.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package outbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/internal"
|
||||||
|
proxyconfig "github.com/v2ray/v2ray-core/proxy/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||||
|
type RawOutbound struct {
|
||||||
|
Receivers []*Receiver `json:"vnext"`
|
||||||
|
}
|
||||||
|
rawOutbound := &RawOutbound{}
|
||||||
|
err := json.Unmarshal(data, rawOutbound)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(rawOutbound.Receivers) == 0 {
|
||||||
|
log.Error("VMess: 0 VMess receiver configured.")
|
||||||
|
return internal.ErrorBadConfiguration
|
||||||
|
}
|
||||||
|
this.Receivers = rawOutbound.Receivers
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proxyconfig.RegisterOutboundConnectionConfig("vmess",
|
||||||
|
func(data []byte) (interface{}, error) {
|
||||||
|
rawConfig := new(Config)
|
||||||
|
if err := json.Unmarshal(data, rawConfig); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return rawConfig, nil
|
||||||
|
})
|
||||||
|
}
|
@ -1,85 +0,0 @@
|
|||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
|
||||||
v2netjson "github.com/v2ray/v2ray-core/common/net/json"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/internal"
|
|
||||||
proxyconfig "github.com/v2ray/v2ray-core/proxy/internal/config"
|
|
||||||
jsonconfig "github.com/v2ray/v2ray-core/proxy/internal/config/json"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/vmess"
|
|
||||||
vmessjson "github.com/v2ray/v2ray-core/proxy/vmess/json"
|
|
||||||
"github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ConfigTarget struct {
|
|
||||||
Destination v2net.Destination
|
|
||||||
Users []*vmessjson.ConfigUser
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *ConfigTarget) UnmarshalJSON(data []byte) error {
|
|
||||||
type RawConfigTarget struct {
|
|
||||||
Address *v2netjson.Host `json:"address"`
|
|
||||||
Port v2net.Port `json:"port"`
|
|
||||||
Users []*vmessjson.ConfigUser `json:"users"`
|
|
||||||
}
|
|
||||||
var rawConfig RawConfigTarget
|
|
||||||
if err := json.Unmarshal(data, &rawConfig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(rawConfig.Users) == 0 {
|
|
||||||
log.Error("0 user configured for VMess outbound.")
|
|
||||||
return internal.ErrorBadConfiguration
|
|
||||||
}
|
|
||||||
t.Users = rawConfig.Users
|
|
||||||
if rawConfig.Address == nil {
|
|
||||||
log.Error("Address is not set in VMess outbound config.")
|
|
||||||
return internal.ErrorBadConfiguration
|
|
||||||
}
|
|
||||||
t.Destination = v2net.TCPDestination(rawConfig.Address.Address(), rawConfig.Port)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Outbound struct {
|
|
||||||
TargetList []*ConfigTarget `json:"vnext"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *Outbound) UnmarshalJSON(data []byte) error {
|
|
||||||
type RawOutbound struct {
|
|
||||||
TargetList []*ConfigTarget `json:"vnext"`
|
|
||||||
}
|
|
||||||
rawOutbound := &RawOutbound{}
|
|
||||||
err := json.Unmarshal(data, rawOutbound)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(rawOutbound.TargetList) == 0 {
|
|
||||||
log.Error("0 VMess receiver configured.")
|
|
||||||
return internal.ErrorBadConfiguration
|
|
||||||
}
|
|
||||||
this.TargetList = rawOutbound.TargetList
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Outbound) Receivers() []*outbound.Receiver {
|
|
||||||
targets := make([]*outbound.Receiver, 0, 2*len(o.TargetList))
|
|
||||||
for _, rawTarget := range o.TargetList {
|
|
||||||
users := make([]vmess.User, 0, len(rawTarget.Users))
|
|
||||||
for _, rawUser := range rawTarget.Users {
|
|
||||||
users = append(users, rawUser)
|
|
||||||
}
|
|
||||||
targets = append(targets, &outbound.Receiver{
|
|
||||||
Destination: rawTarget.Destination,
|
|
||||||
Accounts: users,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return targets
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
proxyconfig.RegisterOutboundConnectionConfig("vmess", jsonconfig.JsonConfigLoader(func() interface{} {
|
|
||||||
return new(Outbound)
|
|
||||||
}))
|
|
||||||
}
|
|
@ -195,10 +195,10 @@ func handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<-
|
|||||||
func init() {
|
func init() {
|
||||||
internal.MustRegisterOutboundConnectionHandlerCreator("vmess",
|
internal.MustRegisterOutboundConnectionHandlerCreator("vmess",
|
||||||
func(space app.Space, rawConfig interface{}) (proxy.OutboundConnectionHandler, error) {
|
func(space app.Space, rawConfig interface{}) (proxy.OutboundConnectionHandler, error) {
|
||||||
vOutConfig := rawConfig.(Config)
|
vOutConfig := rawConfig.(*Config)
|
||||||
return &VMessOutboundHandler{
|
return &VMessOutboundHandler{
|
||||||
space: space,
|
space: space,
|
||||||
receiverManager: NewReceiverManager(vOutConfig.Receivers()),
|
receiverManager: NewReceiverManager(vOutConfig.Receivers),
|
||||||
}, nil
|
}, nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
type Receiver struct {
|
type Receiver struct {
|
||||||
Destination v2net.Destination
|
Destination v2net.Destination
|
||||||
Accounts []vmess.User
|
Accounts []*vmess.User
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReceiverManager struct {
|
type ReceiverManager struct {
|
||||||
@ -22,7 +22,7 @@ func NewReceiverManager(receivers []*Receiver) *ReceiverManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ReceiverManager) PickReceiver() (v2net.Destination, vmess.User) {
|
func (this *ReceiverManager) PickReceiver() (v2net.Destination, *vmess.User) {
|
||||||
receiverLen := len(this.receivers)
|
receiverLen := len(this.receivers)
|
||||||
receiverIdx := 0
|
receiverIdx := 0
|
||||||
if receiverLen > 1 {
|
if receiverLen > 1 {
|
||||||
|
36
proxy/vmess/outbound/receiver_json.go
Normal file
36
proxy/vmess/outbound/receiver_json.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package outbound
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/common/log"
|
||||||
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
v2netjson "github.com/v2ray/v2ray-core/common/net/json"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/internal"
|
||||||
|
"github.com/v2ray/v2ray-core/proxy/vmess"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *Receiver) UnmarshalJSON(data []byte) error {
|
||||||
|
type RawConfigTarget struct {
|
||||||
|
Address *v2netjson.Host `json:"address"`
|
||||||
|
Port v2net.Port `json:"port"`
|
||||||
|
Users []*vmess.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.ErrorBadConfiguration
|
||||||
|
}
|
||||||
|
this.Accounts = rawConfig.Users
|
||||||
|
if rawConfig.Address == nil {
|
||||||
|
log.Error("VMess: Address is not set in VMess outbound config.")
|
||||||
|
return internal.ErrorBadConfiguration
|
||||||
|
}
|
||||||
|
this.Destination = v2net.TCPDestination(rawConfig.Address.Address(), rawConfig.Port)
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,10 +1,12 @@
|
|||||||
package json_test
|
// +build json
|
||||||
|
|
||||||
|
package outbound_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
jsonconfig "github.com/v2ray/v2ray-core/proxy/vmess/outbound/json"
|
. "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
||||||
v2testing "github.com/v2ray/v2ray-core/testing"
|
v2testing "github.com/v2ray/v2ray-core/testing"
|
||||||
"github.com/v2ray/v2ray-core/testing/assert"
|
"github.com/v2ray/v2ray-core/testing/assert"
|
||||||
)
|
)
|
||||||
@ -24,10 +26,10 @@ func TestConfigTargetParsing(t *testing.T) {
|
|||||||
]
|
]
|
||||||
}`
|
}`
|
||||||
|
|
||||||
var target *jsonconfig.ConfigTarget
|
receiver := new(Receiver)
|
||||||
err := json.Unmarshal([]byte(rawJson), &target)
|
err := json.Unmarshal([]byte(rawJson), &receiver)
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
assert.String(target.Destination).Equals("tcp:127.0.0.1:80")
|
assert.String(receiver.Destination).Equals("tcp:127.0.0.1:80")
|
||||||
assert.Int(len(target.Users)).Equals(1)
|
assert.Int(len(receiver.Accounts)).Equals(1)
|
||||||
assert.String(target.Users[0].ID()).Equals("e641f5ad-9397-41e3-bf1a-e8740dfed019")
|
assert.String(receiver.Accounts[0].ID).Equals("e641f5ad-9397-41e3-bf1a-e8740dfed019")
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "github.com/v2ray/v2ray-core/proxy/vmess/protocol"
|
. "github.com/v2ray/v2ray-core/proxy/vmess/protocol"
|
||||||
v2testing "github.com/v2ray/v2ray-core/testing"
|
v2testing "github.com/v2ray/v2ray-core/testing"
|
||||||
"github.com/v2ray/v2ray-core/testing/assert"
|
"github.com/v2ray/v2ray-core/testing/assert"
|
||||||
)
|
)
|
||||||
|
@ -6,17 +6,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type MockUserSet struct {
|
type MockUserSet struct {
|
||||||
Users []vmess.User
|
Users []*vmess.User
|
||||||
UserHashes map[string]int
|
UserHashes map[string]int
|
||||||
Timestamps map[string]protocol.Timestamp
|
Timestamps map[string]protocol.Timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (us *MockUserSet) AddUser(user vmess.User) error {
|
func (us *MockUserSet) AddUser(user *vmess.User) error {
|
||||||
us.Users = append(us.Users, user)
|
us.Users = append(us.Users, user)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (us *MockUserSet) GetUser(userhash []byte) (vmess.User, protocol.Timestamp, bool) {
|
func (us *MockUserSet) GetUser(userhash []byte) (*vmess.User, protocol.Timestamp, bool) {
|
||||||
idx, found := us.UserHashes[string(userhash)]
|
idx, found := us.UserHashes[string(userhash)]
|
||||||
if found {
|
if found {
|
||||||
return us.Users[idx], us.Timestamps[string(userhash)], true
|
return us.Users[idx], us.Timestamps[string(userhash)], true
|
||||||
|
@ -6,34 +6,16 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol"
|
"github.com/v2ray/v2ray-core/proxy/vmess/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StaticUser struct {
|
|
||||||
id *vmess.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StaticUser) ID() *vmess.ID {
|
|
||||||
return this.id
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StaticUser) Level() vmess.UserLevel {
|
|
||||||
return vmess.UserLevelUntrusted
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StaticUser) AlterIDs() []*vmess.ID {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *StaticUser) AnyValidID() *vmess.ID {
|
|
||||||
return this.id
|
|
||||||
}
|
|
||||||
|
|
||||||
type StaticUserSet struct {
|
type StaticUserSet struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (us *StaticUserSet) AddUser(user vmess.User) error {
|
func (us *StaticUserSet) AddUser(user *vmess.User) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (us *StaticUserSet) GetUser(userhash []byte) (vmess.User, protocol.Timestamp, bool) {
|
func (us *StaticUserSet) GetUser(userhash []byte) (*vmess.User, protocol.Timestamp, bool) {
|
||||||
id, _ := uuid.ParseString("703e9102-eb57-499c-8b59-faf4f371bb21")
|
id, _ := uuid.ParseString("703e9102-eb57-499c-8b59-faf4f371bb21")
|
||||||
return &StaticUser{id: vmess.NewID(id)}, 0, true
|
return &vmess.User{
|
||||||
|
ID: vmess.NewID(id),
|
||||||
|
}, 0, true
|
||||||
}
|
}
|
||||||
|
@ -38,12 +38,12 @@ type idEntry struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UserSet interface {
|
type UserSet interface {
|
||||||
AddUser(user vmess.User) error
|
AddUser(user *vmess.User) error
|
||||||
GetUser(timeHash []byte) (vmess.User, Timestamp, bool)
|
GetUser(timeHash []byte) (*vmess.User, Timestamp, bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
type TimedUserSet struct {
|
type TimedUserSet struct {
|
||||||
validUsers []vmess.User
|
validUsers []*vmess.User
|
||||||
userHash map[[16]byte]indexTimePair
|
userHash map[[16]byte]indexTimePair
|
||||||
ids []*idEntry
|
ids []*idEntry
|
||||||
access sync.RWMutex
|
access sync.RWMutex
|
||||||
@ -56,7 +56,7 @@ type indexTimePair struct {
|
|||||||
|
|
||||||
func NewTimedUserSet() UserSet {
|
func NewTimedUserSet() UserSet {
|
||||||
tus := &TimedUserSet{
|
tus := &TimedUserSet{
|
||||||
validUsers: make([]vmess.User, 0, 16),
|
validUsers: make([]*vmess.User, 0, 16),
|
||||||
userHash: make(map[[16]byte]indexTimePair, 512),
|
userHash: make(map[[16]byte]indexTimePair, 512),
|
||||||
access: sync.RWMutex{},
|
access: sync.RWMutex{},
|
||||||
ids: make([]*idEntry, 0, 512),
|
ids: make([]*idEntry, 0, 512),
|
||||||
@ -94,21 +94,21 @@ func (us *TimedUserSet) updateUserHash(tick <-chan time.Time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (us *TimedUserSet) AddUser(user vmess.User) error {
|
func (us *TimedUserSet) AddUser(user *vmess.User) error {
|
||||||
idx := len(us.validUsers)
|
idx := len(us.validUsers)
|
||||||
us.validUsers = append(us.validUsers, user)
|
us.validUsers = append(us.validUsers, user)
|
||||||
|
|
||||||
nowSec := time.Now().Unix()
|
nowSec := time.Now().Unix()
|
||||||
|
|
||||||
entry := &idEntry{
|
entry := &idEntry{
|
||||||
id: user.ID(),
|
id: user.ID,
|
||||||
userIdx: idx,
|
userIdx: idx,
|
||||||
lastSec: Timestamp(nowSec - cacheDurationSec),
|
lastSec: Timestamp(nowSec - cacheDurationSec),
|
||||||
hashes: collect.NewSizedQueue(2*cacheDurationSec + 1),
|
hashes: collect.NewSizedQueue(2*cacheDurationSec + 1),
|
||||||
}
|
}
|
||||||
us.generateNewHashes(Timestamp(nowSec+cacheDurationSec), idx, entry)
|
us.generateNewHashes(Timestamp(nowSec+cacheDurationSec), idx, entry)
|
||||||
us.ids = append(us.ids, entry)
|
us.ids = append(us.ids, entry)
|
||||||
for _, alterid := range user.AlterIDs() {
|
for _, alterid := range user.AlterIDs {
|
||||||
entry := &idEntry{
|
entry := &idEntry{
|
||||||
id: alterid,
|
id: alterid,
|
||||||
userIdx: idx,
|
userIdx: idx,
|
||||||
@ -122,7 +122,7 @@ func (us *TimedUserSet) AddUser(user vmess.User) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (us *TimedUserSet) GetUser(userHash []byte) (vmess.User, Timestamp, bool) {
|
func (us *TimedUserSet) GetUser(userHash []byte) (*vmess.User, Timestamp, bool) {
|
||||||
defer us.access.RUnlock()
|
defer us.access.RUnlock()
|
||||||
us.access.RLock()
|
us.access.RLock()
|
||||||
var fixedSizeHash [16]byte
|
var fixedSizeHash [16]byte
|
||||||
|
@ -34,7 +34,7 @@ const (
|
|||||||
// streaming.
|
// streaming.
|
||||||
type VMessRequest struct {
|
type VMessRequest struct {
|
||||||
Version byte
|
Version byte
|
||||||
User vmess.User
|
User *vmess.User
|
||||||
RequestIV []byte
|
RequestIV []byte
|
||||||
RequestKey []byte
|
RequestKey []byte
|
||||||
ResponseHeader []byte
|
ResponseHeader []byte
|
||||||
@ -83,7 +83,7 @@ func (this *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
|||||||
timestampHash := TimestampHash()
|
timestampHash := TimestampHash()
|
||||||
timestampHash.Write(timeSec.HashBytes())
|
timestampHash.Write(timeSec.HashBytes())
|
||||||
iv := timestampHash.Sum(nil)
|
iv := timestampHash.Sum(nil)
|
||||||
aesStream, err := v2crypto.NewAesDecryptionStream(userObj.ID().CmdKey(), iv)
|
aesStream, err := v2crypto.NewAesDecryptionStream(userObj.ID.CmdKey(), iv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("VMess: Failed to create AES stream: %v", err)
|
log.Debug("VMess: Failed to create AES stream: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -217,7 +217,7 @@ func (this *VMessRequest) ToBytes(timestampGenerator RandomTimestampGenerator, b
|
|||||||
timestampHash := md5.New()
|
timestampHash := md5.New()
|
||||||
timestampHash.Write(timestamp.HashBytes())
|
timestampHash.Write(timestamp.HashBytes())
|
||||||
iv := timestampHash.Sum(nil)
|
iv := timestampHash.Sum(nil)
|
||||||
aesStream, err := v2crypto.NewAesEncryptionStream(this.User.ID().CmdKey(), iv)
|
aesStream, err := v2crypto.NewAesEncryptionStream(this.User.ID.CmdKey(), iv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -24,27 +24,6 @@ func (this *FakeTimestampGenerator) Next() Timestamp {
|
|||||||
return this.timestamp
|
return this.timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestUser struct {
|
|
||||||
id *vmess.ID
|
|
||||||
level vmess.UserLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *TestUser) ID() *vmess.ID {
|
|
||||||
return u.id
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *TestUser) Level() vmess.UserLevel {
|
|
||||||
return this.level
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *TestUser) AlterIDs() []*vmess.ID {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this *TestUser) AnyValidID() *vmess.ID {
|
|
||||||
return this.id
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestVMessSerialization(t *testing.T) {
|
func TestVMessSerialization(t *testing.T) {
|
||||||
v2testing.Current(t)
|
v2testing.Current(t)
|
||||||
|
|
||||||
@ -53,11 +32,11 @@ func TestVMessSerialization(t *testing.T) {
|
|||||||
|
|
||||||
userId := vmess.NewID(id)
|
userId := vmess.NewID(id)
|
||||||
|
|
||||||
testUser := &TestUser{
|
testUser := &vmess.User{
|
||||||
id: userId,
|
ID: userId,
|
||||||
}
|
}
|
||||||
|
|
||||||
userSet := protocoltesting.MockUserSet{[]vmess.User{}, make(map[string]int), make(map[string]Timestamp)}
|
userSet := protocoltesting.MockUserSet{[]*vmess.User{}, make(map[string]int), make(map[string]Timestamp)}
|
||||||
userSet.AddUser(testUser)
|
userSet.AddUser(testUser)
|
||||||
|
|
||||||
request := new(VMessRequest)
|
request := new(VMessRequest)
|
||||||
@ -92,7 +71,7 @@ func TestVMessSerialization(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert.Byte(actualRequest.Version).Named("Version").Equals(byte(0x01))
|
assert.Byte(actualRequest.Version).Named("Version").Equals(byte(0x01))
|
||||||
assert.String(actualRequest.User.ID()).Named("UserId").Equals(request.User.ID().String())
|
assert.String(actualRequest.User.ID).Named("UserId").Equals(request.User.ID.String())
|
||||||
assert.Bytes(actualRequest.RequestIV).Named("RequestIV").Equals(request.RequestIV[:])
|
assert.Bytes(actualRequest.RequestIV).Named("RequestIV").Equals(request.RequestIV[:])
|
||||||
assert.Bytes(actualRequest.RequestKey).Named("RequestKey").Equals(request.RequestKey[:])
|
assert.Bytes(actualRequest.RequestKey).Named("RequestKey").Equals(request.RequestKey[:])
|
||||||
assert.Bytes(actualRequest.ResponseHeader).Named("ResponseHeader").Equals(request.ResponseHeader[:])
|
assert.Bytes(actualRequest.ResponseHeader).Named("ResponseHeader").Equals(request.ResponseHeader[:])
|
||||||
@ -113,10 +92,10 @@ func BenchmarkVMessRequestWriting(b *testing.B) {
|
|||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
|
|
||||||
userId := vmess.NewID(id)
|
userId := vmess.NewID(id)
|
||||||
userSet := protocoltesting.MockUserSet{[]vmess.User{}, make(map[string]int), make(map[string]Timestamp)}
|
userSet := protocoltesting.MockUserSet{[]*vmess.User{}, make(map[string]int), make(map[string]Timestamp)}
|
||||||
|
|
||||||
testUser := &TestUser{
|
testUser := &vmess.User{
|
||||||
id: userId,
|
ID: userId,
|
||||||
}
|
}
|
||||||
userSet.AddUser(testUser)
|
userSet.AddUser(testUser)
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package vmess
|
package vmess
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
)
|
||||||
|
|
||||||
type UserLevel int
|
type UserLevel int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -7,11 +11,21 @@ const (
|
|||||||
UserLevelUntrusted = UserLevel(0)
|
UserLevelUntrusted = UserLevel(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
type User interface {
|
type User struct {
|
||||||
ID() *ID
|
ID *ID
|
||||||
AlterIDs() []*ID
|
AlterIDs []*ID
|
||||||
Level() UserLevel
|
Level UserLevel
|
||||||
AnyValidID() *ID
|
}
|
||||||
|
|
||||||
|
func (this *User) AnyValidID() *ID {
|
||||||
|
if len(this.AlterIDs) == 0 {
|
||||||
|
return this.ID
|
||||||
|
}
|
||||||
|
if len(this.AlterIDs) == 1 {
|
||||||
|
return this.AlterIDs[0]
|
||||||
|
}
|
||||||
|
idx := rand.Intn(len(this.AlterIDs))
|
||||||
|
return this.AlterIDs[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserSettings struct {
|
type UserSettings struct {
|
||||||
|
42
proxy/vmess/user_json.go
Normal file
42
proxy/vmess/user_json.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// +build json
|
||||||
|
|
||||||
|
package vmess
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/common/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (u *User) UnmarshalJSON(data []byte) error {
|
||||||
|
type rawUser struct {
|
||||||
|
IdString string `json:"id"`
|
||||||
|
EmailString string `json:"email"`
|
||||||
|
LevelInt int `json:"level"`
|
||||||
|
AlterIdCount int `json:"alterId"`
|
||||||
|
}
|
||||||
|
var rawUserValue rawUser
|
||||||
|
if err := json.Unmarshal(data, &rawUserValue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
id, err := uuid.ParseString(rawUserValue.IdString)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
u.ID = NewID(id)
|
||||||
|
//u.Email = rawUserValue.EmailString
|
||||||
|
u.Level = UserLevel(rawUserValue.LevelInt)
|
||||||
|
|
||||||
|
if rawUserValue.AlterIdCount > 0 {
|
||||||
|
prevId := u.ID.UUID()
|
||||||
|
// TODO: check duplicate
|
||||||
|
u.AlterIDs = make([]*ID, rawUserValue.AlterIdCount)
|
||||||
|
for idx, _ := range u.AlterIDs {
|
||||||
|
newid := prevId.Next()
|
||||||
|
u.AlterIDs[idx] = NewID(newid)
|
||||||
|
prevId = newid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -13,9 +13,7 @@ import (
|
|||||||
proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks"
|
proxymocks "github.com/v2ray/v2ray-core/proxy/testing/mocks"
|
||||||
vmess "github.com/v2ray/v2ray-core/proxy/vmess"
|
vmess "github.com/v2ray/v2ray-core/proxy/vmess"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound"
|
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound/json"
|
|
||||||
"github.com/v2ray/v2ray-core/shell/point"
|
"github.com/v2ray/v2ray-core/shell/point"
|
||||||
"github.com/v2ray/v2ray-core/shell/point/testing/mocks"
|
"github.com/v2ray/v2ray-core/shell/point/testing/mocks"
|
||||||
v2testing "github.com/v2ray/v2ray-core/testing"
|
v2testing "github.com/v2ray/v2ray-core/testing"
|
||||||
|
@ -16,19 +16,12 @@ import (
|
|||||||
|
|
||||||
// The following are neccesary as they register handlers in their init functions.
|
// The following are neccesary as they register handlers in their init functions.
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/blackhole"
|
_ "github.com/v2ray/v2ray-core/proxy/blackhole"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/blackhole/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/dokodemo"
|
_ "github.com/v2ray/v2ray-core/proxy/dokodemo"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/dokodemo/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/freedom"
|
_ "github.com/v2ray/v2ray-core/proxy/freedom"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/freedom/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/http"
|
_ "github.com/v2ray/v2ray-core/proxy/http"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/http/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/socks"
|
_ "github.com/v2ray/v2ray-core/proxy/socks"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/socks/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound"
|
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound/json"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -5,11 +5,11 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
netassert "github.com/v2ray/v2ray-core/common/net/testing/assert"
|
netassert "github.com/v2ray/v2ray-core/common/net/testing/assert"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/dokodemo/json"
|
_ "github.com/v2ray/v2ray-core/proxy/dokodemo"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/freedom/json"
|
_ "github.com/v2ray/v2ray-core/proxy/freedom"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/socks/json"
|
_ "github.com/v2ray/v2ray-core/proxy/socks"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound/json"
|
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound/json"
|
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
||||||
"github.com/v2ray/v2ray-core/shell/point/json"
|
"github.com/v2ray/v2ray-core/shell/point/json"
|
||||||
|
|
||||||
v2testing "github.com/v2ray/v2ray-core/testing"
|
v2testing "github.com/v2ray/v2ray-core/testing"
|
||||||
|
@ -13,17 +13,11 @@ import (
|
|||||||
|
|
||||||
// The following are neccesary as they register handlers in their init functions.
|
// The following are neccesary as they register handlers in their init functions.
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/blackhole"
|
_ "github.com/v2ray/v2ray-core/proxy/blackhole"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/blackhole/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/dokodemo"
|
_ "github.com/v2ray/v2ray-core/proxy/dokodemo"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/dokodemo/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/freedom"
|
_ "github.com/v2ray/v2ray-core/proxy/freedom"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/freedom/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/socks"
|
_ "github.com/v2ray/v2ray-core/proxy/socks"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/socks/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound"
|
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/inbound/json"
|
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound"
|
||||||
_ "github.com/v2ray/v2ray-core/proxy/vmess/outbound/json"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -14,7 +14,7 @@ func buildV2Ray(targetFile string, version string, goOS GoOS, goArch GoArch) err
|
|||||||
today := fmt.Sprintf("%04d%02d%02d", year, int(month), day)
|
today := fmt.Sprintf("%04d%02d%02d", year, int(month), day)
|
||||||
ldFlags = ldFlags + " -X github.com/v2ray/v2ray-core.version=" + version + " -X github.com/v2ray/v2ray-core.build=" + today
|
ldFlags = ldFlags + " -X github.com/v2ray/v2ray-core.version=" + version + " -X github.com/v2ray/v2ray-core.build=" + today
|
||||||
}
|
}
|
||||||
cmd := exec.Command("go", "build", "-o", targetFile, "-compiler", "gc", "-ldflags", ldFlags, "github.com/v2ray/v2ray-core/release/server")
|
cmd := exec.Command("go", "build", "-tags", "json", "-o", targetFile, "-compiler", "gc", "-ldflags", ldFlags, "github.com/v2ray/v2ray-core/release/server")
|
||||||
cmd.Env = append(cmd.Env, "GOOS="+string(goOS), "GOARCH="+string(goArch))
|
cmd.Env = append(cmd.Env, "GOOS="+string(goOS), "GOARCH="+string(goArch))
|
||||||
cmd.Env = append(cmd.Env, os.Environ()...)
|
cmd.Env = append(cmd.Env, os.Environ()...)
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user