mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 17:46:58 -05:00
massive refactoring for configuration
This commit is contained in:
parent
791ac780f0
commit
0ca7dab49b
@ -1,37 +0,0 @@
|
|||||||
// Package json contains io library for VConfig in Json format.
|
|
||||||
package json
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
_ "fmt"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core"
|
|
||||||
)
|
|
||||||
|
|
||||||
type JsonVUser struct {
|
|
||||||
id string `json:"id"`
|
|
||||||
email string `json:"email"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type JsonVConfig struct {
|
|
||||||
Port uint8 `json:"port"`
|
|
||||||
Clients []JsonVUser `json:"users"`
|
|
||||||
Protocol string `json:"protocol"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type JsonVConfigUnmarshaller struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func StringToVUser(id string) (u core.VUser, err error) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*JsonVConfigUnmarshaller) Unmarshall(data []byte) (*core.VConfig, error) {
|
|
||||||
var jsonConfig JsonVConfig
|
|
||||||
err := json.Unmarshal(data, &jsonConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var vconfig = new(core.VConfig)
|
|
||||||
return vconfig, nil
|
|
||||||
}
|
|
@ -16,6 +16,7 @@ const (
|
|||||||
AuthNotRequired = byte(0x00)
|
AuthNotRequired = byte(0x00)
|
||||||
AuthGssApi = byte(0x01)
|
AuthGssApi = byte(0x01)
|
||||||
AuthUserPass = byte(0x02)
|
AuthUserPass = byte(0x02)
|
||||||
|
AuthNoMatchingMethod = byte(0xFF)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Authentication request header of Socks5 protocol
|
// Authentication request header of Socks5 protocol
|
||||||
|
@ -28,6 +28,11 @@ func writeLog(data string, level LogLevel) {
|
|||||||
log.Print(data)
|
log.Print(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Debug(format string, v ...interface{}) {
|
||||||
|
data := fmt.Sprintf(format, v)
|
||||||
|
writeLog("[Debug]"+data, DebugLevel)
|
||||||
|
}
|
||||||
|
|
||||||
func Info(format string, v ...interface{}) {
|
func Info(format string, v ...interface{}) {
|
||||||
data := fmt.Sprintf(format, v)
|
data := fmt.Sprintf(format, v)
|
||||||
writeLog("[Info]"+data, InfoLevel)
|
writeLog("[Info]"+data, InfoLevel)
|
||||||
|
@ -10,13 +10,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type VFreeConnection struct {
|
type VFreeConnection struct {
|
||||||
vPoint *core.VPoint
|
|
||||||
dest v2net.VAddress
|
dest v2net.VAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVFreeConnection(vp *core.VPoint, dest v2net.VAddress) *VFreeConnection {
|
func NewVFreeConnection(dest v2net.VAddress) *VFreeConnection {
|
||||||
conn := new(VFreeConnection)
|
conn := new(VFreeConnection)
|
||||||
conn.vPoint = vp
|
|
||||||
conn.dest = dest
|
conn.dest = dest
|
||||||
return conn
|
return conn
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,6 @@ import (
|
|||||||
type FreedomFactory struct {
|
type FreedomFactory struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (factory FreedomFactory) Create(vp *core.VPoint, dest v2net.VAddress) (core.OutboundConnectionHandler, error) {
|
func (factory FreedomFactory) Create(vp *core.VPoint, config []byte, dest v2net.VAddress) (core.OutboundConnectionHandler, error) {
|
||||||
return NewVFreeConnection(vp, dest), nil
|
return NewVFreeConnection(dest), nil
|
||||||
}
|
}
|
||||||
|
22
net/socks/config.go
Normal file
22
net/socks/config.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package socks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
JsonAuthMethodNoAuth = "noauth"
|
||||||
|
JsonAuthMethodUserPass = "password"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SocksConfig struct {
|
||||||
|
AuthMethod string `json:"auth"`
|
||||||
|
Username string `json:"user"`
|
||||||
|
Password string `json:"pass"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfig(rawConfig []byte) (SocksConfig, error) {
|
||||||
|
config := SocksConfig{}
|
||||||
|
err := json.Unmarshal(rawConfig, &config)
|
||||||
|
return config, err
|
||||||
|
}
|
@ -3,12 +3,12 @@ package socks
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core"
|
"github.com/v2ray/v2ray-core"
|
||||||
socksio "github.com/v2ray/v2ray-core/io/socks"
|
socksio "github.com/v2ray/v2ray-core/io/socks"
|
||||||
|
"github.com/v2ray/v2ray-core/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -20,18 +20,24 @@ var (
|
|||||||
type SocksServer struct {
|
type SocksServer struct {
|
||||||
accepting bool
|
accepting bool
|
||||||
vPoint *core.VPoint
|
vPoint *core.VPoint
|
||||||
|
config SocksConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSocksServer(vp *core.VPoint) *SocksServer {
|
func NewSocksServer(vp *core.VPoint, rawConfig []byte) *SocksServer {
|
||||||
server := new(SocksServer)
|
server := new(SocksServer)
|
||||||
server.vPoint = vp
|
server.vPoint = vp
|
||||||
|
config, err := loadConfig(rawConfig)
|
||||||
|
if err != nil {
|
||||||
|
panic(log.Error("Unable to load socks config: %v", err))
|
||||||
|
}
|
||||||
|
server.config = config
|
||||||
return server
|
return server
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *SocksServer) Listen(port uint16) error {
|
func (server *SocksServer) Listen(port uint16) error {
|
||||||
listener, err := net.Listen("tcp", ":"+strconv.Itoa(int(port)))
|
listener, err := net.Listen("tcp", ":"+strconv.Itoa(int(port)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return log.Error("Error on listening port %d: %v", port, err)
|
||||||
}
|
}
|
||||||
server.accepting = true
|
server.accepting = true
|
||||||
go server.AcceptConnections(listener)
|
go server.AcceptConnections(listener)
|
||||||
@ -42,8 +48,7 @@ func (server *SocksServer) AcceptConnections(listener net.Listener) error {
|
|||||||
for server.accepting {
|
for server.accepting {
|
||||||
connection, err := listener.Accept()
|
connection, err := listener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
return log.Error("Error on accepting socks connection: %v", err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
go server.HandleConnection(connection)
|
go server.HandleConnection(connection)
|
||||||
}
|
}
|
||||||
@ -55,14 +60,19 @@ func (server *SocksServer) HandleConnection(connection net.Conn) error {
|
|||||||
|
|
||||||
auth, err := socksio.ReadAuthentication(connection)
|
auth, err := socksio.ReadAuthentication(connection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
return log.Error("Error on reading authentication: %v", err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
log.Print(auth)
|
|
||||||
|
|
||||||
if !auth.HasAuthMethod(socksio.AuthNotRequired) {
|
expectedAuthMethod := socksio.AuthNotRequired
|
||||||
// TODO send response with FF
|
if server.config.AuthMethod == JsonAuthMethodUserPass {
|
||||||
log.Print(ErrorAuthenticationFailed)
|
expectedAuthMethod = socksio.AuthUserPass
|
||||||
|
}
|
||||||
|
|
||||||
|
if !auth.HasAuthMethod(expectedAuthMethod) {
|
||||||
|
authResponse := socksio.NewAuthenticationResponse(socksio.AuthNoMatchingMethod)
|
||||||
|
socksio.WriteAuthentication(connection, authResponse)
|
||||||
|
|
||||||
|
log.Info("Client doesn't support allowed any auth methods.")
|
||||||
return ErrorAuthenticationFailed
|
return ErrorAuthenticationFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,8 +81,7 @@ func (server *SocksServer) HandleConnection(connection net.Conn) error {
|
|||||||
|
|
||||||
request, err := socksio.ReadRequest(connection)
|
request, err := socksio.ReadRequest(connection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
return log.Error("Error on reading socks request: %v", err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response := socksio.NewSocks5Response()
|
response := socksio.NewSocks5Response()
|
||||||
@ -81,7 +90,7 @@ func (server *SocksServer) HandleConnection(connection net.Conn) error {
|
|||||||
response := socksio.NewSocks5Response()
|
response := socksio.NewSocks5Response()
|
||||||
response.Error = socksio.ErrorCommandNotSupported
|
response.Error = socksio.ErrorCommandNotSupported
|
||||||
socksio.WriteResponse(connection, response)
|
socksio.WriteResponse(connection, response)
|
||||||
log.Print(ErrorCommandNotSupported)
|
log.Info("Unsupported socks command %d", request.Command)
|
||||||
return ErrorCommandNotSupported
|
return ErrorCommandNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +123,7 @@ func (server *SocksServer) dumpInput(conn net.Conn, input chan<- []byte, finish
|
|||||||
for {
|
for {
|
||||||
buffer := make([]byte, 256)
|
buffer := make([]byte, 256)
|
||||||
nBytes, err := conn.Read(buffer)
|
nBytes, err := conn.Read(buffer)
|
||||||
log.Printf("Reading %d bytes, with error %v", nBytes, err)
|
log.Debug("Reading %d bytes, with error %v", nBytes, err)
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
close(input)
|
close(input)
|
||||||
finish <- true
|
finish <- true
|
||||||
@ -132,7 +141,7 @@ func (server *SocksServer) dumpOutput(conn net.Conn, output <-chan []byte, finis
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
nBytes, _ := conn.Write(buffer)
|
nBytes, _ := conn.Write(buffer)
|
||||||
log.Printf("Writing %d bytes", nBytes)
|
log.Debug("Writing %d bytes", nBytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,6 @@ import (
|
|||||||
type SocksServerFactory struct {
|
type SocksServerFactory struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (factory SocksServerFactory) Create(vp *core.VPoint) (core.InboundConnectionHandler, error) {
|
func (factory SocksServerFactory) Create(vp *core.VPoint, config []byte) (core.InboundConnectionHandler, error) {
|
||||||
return NewSocksServer(vp), nil
|
return NewSocksServer(vp, config), nil
|
||||||
}
|
}
|
||||||
|
40
net/vmess/config.go
Normal file
40
net/vmess/config.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package vmess
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core"
|
||||||
|
v2net "github.com/v2ray/v2ray-core/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type VMessInboundConfig struct {
|
||||||
|
AllowedClients []core.VUser `json:"clients"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadInboundConfig(rawConfig []byte) (VMessInboundConfig, error) {
|
||||||
|
config := VMessInboundConfig{}
|
||||||
|
err := json.Unmarshal(rawConfig, &config)
|
||||||
|
return config, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type VNextConfig struct {
|
||||||
|
Address string `json:"address"`
|
||||||
|
Port uint16 `json:"port"`
|
||||||
|
Users []core.VUser `json:"users"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (config VNextConfig) ToVNextServer() VNextServer {
|
||||||
|
return VNextServer{
|
||||||
|
v2net.DomainAddress(config.Address, config.Port),
|
||||||
|
config.Users}
|
||||||
|
}
|
||||||
|
|
||||||
|
type VMessOutboundConfig struct {
|
||||||
|
VNextList []VNextConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadOutboundConfig(rawConfig []byte) (VMessOutboundConfig, error) {
|
||||||
|
config := VMessOutboundConfig{}
|
||||||
|
err := json.Unmarshal(rawConfig, &config)
|
||||||
|
return config, err
|
||||||
|
}
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core"
|
"github.com/v2ray/v2ray-core"
|
||||||
v2io "github.com/v2ray/v2ray-core/io"
|
v2io "github.com/v2ray/v2ray-core/io"
|
||||||
vmessio "github.com/v2ray/v2ray-core/io/vmess"
|
vmessio "github.com/v2ray/v2ray-core/io/vmess"
|
||||||
|
"github.com/v2ray/v2ray-core/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type VMessInboundHandler struct {
|
type VMessInboundHandler struct {
|
||||||
@ -89,6 +90,7 @@ func (handler *VMessInboundHandler) dumpInput(reader io.Reader, input chan<- []b
|
|||||||
buffer := make([]byte, BufferSize)
|
buffer := make([]byte, BufferSize)
|
||||||
nBytes, err := reader.Read(buffer)
|
nBytes, err := reader.Read(buffer)
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
|
close(input)
|
||||||
finish <- true
|
finish <- true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -114,18 +116,16 @@ func (handler *VMessInboundHandler) waitForFinish(finish <-chan bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VMessInboundHandlerFactory struct {
|
type VMessInboundHandlerFactory struct {
|
||||||
allowedClients *core.VUserSet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVMessInboundHandlerFactory(clients []core.VUser) *VMessInboundHandlerFactory {
|
func (factory *VMessInboundHandlerFactory) Create(vp *core.VPoint, rawConfig []byte) *VMessInboundHandler {
|
||||||
factory := new(VMessInboundHandlerFactory)
|
config, err := loadInboundConfig(rawConfig)
|
||||||
factory.allowedClients = core.NewVUserSet()
|
if err != nil {
|
||||||
for _, user := range clients {
|
panic(log.Error("Failed to load VMess inbound config: %v", err))
|
||||||
factory.allowedClients.AddUser(user)
|
|
||||||
}
|
}
|
||||||
return factory
|
allowedClients := core.NewVUserSet()
|
||||||
}
|
for _, user := range config.AllowedClients {
|
||||||
|
allowedClients.AddUser(user)
|
||||||
func (factory *VMessInboundHandlerFactory) Create(vp *core.VPoint) *VMessInboundHandler {
|
}
|
||||||
return NewVMessInboundHandler(vp, factory.allowedClients)
|
return NewVMessInboundHandler(vp, allowedClients)
|
||||||
}
|
}
|
||||||
|
@ -10,28 +10,37 @@ import (
|
|||||||
"github.com/v2ray/v2ray-core"
|
"github.com/v2ray/v2ray-core"
|
||||||
v2io "github.com/v2ray/v2ray-core/io"
|
v2io "github.com/v2ray/v2ray-core/io"
|
||||||
vmessio "github.com/v2ray/v2ray-core/io/vmess"
|
vmessio "github.com/v2ray/v2ray-core/io/vmess"
|
||||||
|
"github.com/v2ray/v2ray-core/log"
|
||||||
v2net "github.com/v2ray/v2ray-core/net"
|
v2net "github.com/v2ray/v2ray-core/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// VNext is the next VPoint server in the connection chain.
|
||||||
|
type VNextServer struct {
|
||||||
|
Address v2net.VAddress // Address of VNext server
|
||||||
|
Users []core.VUser // User accounts for accessing VNext.
|
||||||
|
}
|
||||||
|
|
||||||
type VMessOutboundHandler struct {
|
type VMessOutboundHandler struct {
|
||||||
vPoint *core.VPoint
|
vPoint *core.VPoint
|
||||||
dest v2net.VAddress
|
dest v2net.VAddress
|
||||||
|
vNextList []VNextServer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVMessOutboundHandler(vp *core.VPoint, dest v2net.VAddress) *VMessOutboundHandler {
|
func NewVMessOutboundHandler(vp *core.VPoint, vNextList []VNextServer, dest v2net.VAddress) *VMessOutboundHandler {
|
||||||
handler := new(VMessOutboundHandler)
|
handler := new(VMessOutboundHandler)
|
||||||
handler.vPoint = vp
|
handler.vPoint = vp
|
||||||
handler.dest = dest
|
handler.dest = dest
|
||||||
|
handler.vNextList = vNextList
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *VMessOutboundHandler) pickVNext() (v2net.VAddress, core.VUser) {
|
func (handler *VMessOutboundHandler) pickVNext() (v2net.VAddress, core.VUser) {
|
||||||
vNextLen := len(handler.vPoint.Config.VNextList)
|
vNextLen := len(handler.vNextList)
|
||||||
if vNextLen == 0 {
|
if vNextLen == 0 {
|
||||||
panic("Zero vNext is configured.")
|
panic("Zero vNext is configured.")
|
||||||
}
|
}
|
||||||
vNextIndex := mrand.Intn(vNextLen)
|
vNextIndex := mrand.Intn(vNextLen)
|
||||||
vNext := handler.vPoint.Config.VNextList[vNextIndex]
|
vNext := handler.vNextList[vNextIndex]
|
||||||
vNextUserLen := len(vNext.Users)
|
vNextUserLen := len(vNext.Users)
|
||||||
if vNextUserLen == 0 {
|
if vNextUserLen == 0 {
|
||||||
panic("Zero User account.")
|
panic("Zero User account.")
|
||||||
@ -91,6 +100,7 @@ func (handler *VMessOutboundHandler) dumpOutput(reader io.Reader, output chan<-
|
|||||||
buffer := make([]byte, BufferSize)
|
buffer := make([]byte, BufferSize)
|
||||||
nBytes, err := reader.Read(buffer)
|
nBytes, err := reader.Read(buffer)
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
|
close(output)
|
||||||
finish <- true
|
finish <- true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -118,6 +128,14 @@ func (handler *VMessOutboundHandler) waitForFinish(finish <-chan bool) {
|
|||||||
type VMessOutboundHandlerFactory struct {
|
type VMessOutboundHandlerFactory struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (factory *VMessOutboundHandlerFactory) Create(vp *core.VPoint, destination v2net.VAddress) *VMessOutboundHandler {
|
func (factory *VMessOutboundHandlerFactory) Create(vp *core.VPoint, rawConfig []byte, destination v2net.VAddress) *VMessOutboundHandler {
|
||||||
return NewVMessOutboundHandler(vp, destination)
|
config, err := loadOutboundConfig(rawConfig)
|
||||||
|
if err != nil {
|
||||||
|
panic(log.Error("Failed to load VMess outbound config: %v", err))
|
||||||
|
}
|
||||||
|
servers := make([]VNextServer, 0, len(config.VNextList))
|
||||||
|
for _, server := range config.VNextList {
|
||||||
|
servers = append(servers, server.ToVNextServer())
|
||||||
|
}
|
||||||
|
return NewVMessOutboundHandler(vp, servers, destination)
|
||||||
}
|
}
|
||||||
|
5
release/server/main.go
Normal file
5
release/server/main.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
}
|
@ -1,37 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core"
|
|
||||||
"github.com/v2ray/v2ray-core/net/freedom"
|
|
||||||
"github.com/v2ray/v2ray-core/net/socks"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
port := uint16(8888)
|
|
||||||
|
|
||||||
uuid := "2418d087-648d-4990-86e8-19dca1d006d3"
|
|
||||||
vid, err := core.UUIDToVID(uuid)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
config := core.VConfig{
|
|
||||||
port,
|
|
||||||
[]core.VUser{core.VUser{vid}},
|
|
||||||
"",
|
|
||||||
[]core.VNext{}}
|
|
||||||
|
|
||||||
vpoint, err := core.NewVPoint(&config, socks.SocksServerFactory{}, freedom.FreedomFactory{})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
err = vpoint.Start()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
finish := make(chan bool)
|
|
||||||
<-finish
|
|
||||||
}
|
|
28
vconfig.go
28
vconfig.go
@ -1,32 +1,28 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
v2net "github.com/v2ray/v2ray-core/net"
|
"encoding/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VUser is the user account that is used for connection to a VPoint
|
// VUser is the user account that is used for connection to a VPoint
|
||||||
type VUser struct {
|
type VUser struct {
|
||||||
Id VID // The ID of this VUser.
|
Id VID `json:"id"` // The ID of this VUser.
|
||||||
}
|
}
|
||||||
|
|
||||||
// VNext is the next VPoint server in the connection chain.
|
type VConnectionConfig struct {
|
||||||
type VNext struct {
|
Protocol string `json:"protocol"`
|
||||||
Address v2net.VAddress // Address of VNext server
|
File string `json:"file"`
|
||||||
Users []VUser // User accounts for accessing VNext.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VConfig is the config for VPoint server.
|
// VConfig is the config for VPoint server.
|
||||||
type VConfig struct {
|
type VConfig struct {
|
||||||
Port uint16 // Port of this VPoint server.
|
Port uint16 `json:"port"` // Port of this VPoint server.
|
||||||
AllowedClients []VUser
|
InboundConfig VConnectionConfig `json:"inbound"`
|
||||||
ClientProtocol string
|
OutboundConfig VConnectionConfig `json:"outbound"`
|
||||||
VNextList []VNext
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type VConfigMarshaller interface {
|
func LoadVConfig(rawConfig []byte) (VConfig, error) {
|
||||||
Marshal(config VConfig) ([]byte, error)
|
config := VConfig{}
|
||||||
}
|
err := json.Unmarshal(rawConfig, &config)
|
||||||
|
return config, err
|
||||||
type VConfigUnmarshaller interface {
|
|
||||||
Unmarshal(data []byte) (VConfig, error)
|
|
||||||
}
|
}
|
||||||
|
67
vpoint.go
67
vpoint.go
@ -1,31 +1,76 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/log"
|
||||||
v2net "github.com/v2ray/v2ray-core/net"
|
v2net "github.com/v2ray/v2ray-core/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
inboundFactories = make(map[string]InboundConnectionHandlerFactory)
|
||||||
|
outboundFactories = make(map[string]OutboundConnectionHandlerFactory)
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterInboundConnectionHandlerFactory(name string, factory InboundConnectionHandlerFactory) error {
|
||||||
|
// TODO check name
|
||||||
|
inboundFactories[name] = factory
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterOutboundConnectionHandlerFactory(name string, factory OutboundConnectionHandlerFactory) error {
|
||||||
|
// TODO check name
|
||||||
|
outboundFactories[name] = factory
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// VPoint is an single server in V2Ray system.
|
// VPoint is an single server in V2Ray system.
|
||||||
type VPoint struct {
|
type VPoint struct {
|
||||||
Config VConfig
|
port uint16
|
||||||
ichFactory InboundConnectionHandlerFactory
|
ichFactory InboundConnectionHandlerFactory
|
||||||
|
ichConfig []byte
|
||||||
ochFactory OutboundConnectionHandlerFactory
|
ochFactory OutboundConnectionHandlerFactory
|
||||||
|
ochConfig []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewVPoint returns a new VPoint server based on given configuration.
|
// NewVPoint returns a new VPoint server based on given configuration.
|
||||||
// The server is not started at this point.
|
// The server is not started at this point.
|
||||||
func NewVPoint(config *VConfig, ichFactory InboundConnectionHandlerFactory, ochFactory OutboundConnectionHandlerFactory) (*VPoint, error) {
|
func NewVPoint(config VConfig) (*VPoint, error) {
|
||||||
var vpoint = new(VPoint)
|
var vpoint = new(VPoint)
|
||||||
vpoint.Config = *config
|
vpoint.port = config.Port
|
||||||
|
|
||||||
|
ichFactory, ok := inboundFactories[config.InboundConfig.Protocol]
|
||||||
|
if !ok {
|
||||||
|
panic(log.Error("Unknown inbound connection handler factory %s", config.InboundConfig.Protocol))
|
||||||
|
}
|
||||||
vpoint.ichFactory = ichFactory
|
vpoint.ichFactory = ichFactory
|
||||||
|
if len(config.InboundConfig.File) > 0 {
|
||||||
|
ichConfig, err := ioutil.ReadFile(config.InboundConfig.File)
|
||||||
|
if err != nil {
|
||||||
|
panic(log.Error("Unable to read config file %v", err))
|
||||||
|
}
|
||||||
|
vpoint.ichConfig = ichConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
ochFactory, ok := outboundFactories[config.OutboundConfig.Protocol]
|
||||||
|
if !ok {
|
||||||
|
panic(log.Error("Unknown outbound connection handler factory %s", config.OutboundConfig.Protocol))
|
||||||
|
}
|
||||||
|
|
||||||
vpoint.ochFactory = ochFactory
|
vpoint.ochFactory = ochFactory
|
||||||
|
if len(config.OutboundConfig.File) > 0 {
|
||||||
|
ochConfig, err := ioutil.ReadFile(config.OutboundConfig.File)
|
||||||
|
if err != nil {
|
||||||
|
panic(log.Error("Unable to read config file %v", err))
|
||||||
|
}
|
||||||
|
vpoint.ochConfig = ochConfig
|
||||||
|
}
|
||||||
|
|
||||||
return vpoint, nil
|
return vpoint, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type InboundConnectionHandlerFactory interface {
|
type InboundConnectionHandlerFactory interface {
|
||||||
Create(vPoint *VPoint) (InboundConnectionHandler, error)
|
Create(vp *VPoint, config []byte) (InboundConnectionHandler, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type InboundConnectionHandler interface {
|
type InboundConnectionHandler interface {
|
||||||
@ -33,7 +78,7 @@ type InboundConnectionHandler interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type OutboundConnectionHandlerFactory interface {
|
type OutboundConnectionHandlerFactory interface {
|
||||||
Create(vPoint *VPoint, dest v2net.VAddress) (OutboundConnectionHandler, error)
|
Create(VP *VPoint, config []byte, dest v2net.VAddress) (OutboundConnectionHandler, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type OutboundConnectionHandler interface {
|
type OutboundConnectionHandler interface {
|
||||||
@ -43,21 +88,21 @@ type OutboundConnectionHandler interface {
|
|||||||
// Start starts the VPoint server, and return any error during the process.
|
// Start starts the VPoint server, and return any error during the process.
|
||||||
// In the case of any errors, the state of the server is unpredicatable.
|
// In the case of any errors, the state of the server is unpredicatable.
|
||||||
func (vp *VPoint) Start() error {
|
func (vp *VPoint) Start() error {
|
||||||
if vp.Config.Port <= 0 {
|
if vp.port <= 0 {
|
||||||
return fmt.Errorf("Invalid port %d", vp.Config.Port)
|
return log.Error("Invalid port %d", vp.port)
|
||||||
}
|
}
|
||||||
inboundConnectionHandler, err := vp.ichFactory.Create(vp)
|
inboundConnectionHandler, err := vp.ichFactory.Create(vp, vp.ichConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = inboundConnectionHandler.Listen(vp.Config.Port)
|
err = inboundConnectionHandler.Listen(vp.port)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vp *VPoint) NewInboundConnectionAccepted(destination v2net.VAddress) InboundVRay {
|
func (vp *VPoint) NewInboundConnectionAccepted(destination v2net.VAddress) InboundVRay {
|
||||||
ray := NewVRay()
|
ray := NewVRay()
|
||||||
// TODO: handle error
|
// TODO: handle error
|
||||||
och, _ := vp.ochFactory.Create(vp, destination)
|
och, _ := vp.ochFactory.Create(vp, vp.ochConfig, destination)
|
||||||
_ = och.Start(ray)
|
_ = och.Start(ray)
|
||||||
return ray
|
return ray
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user