mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-21 01:27:03 -05:00
connecting dots
This commit is contained in:
parent
1c618e93b1
commit
0a96b8fb1d
27
io/aes.go
Normal file
27
io/aes.go
Normal file
@ -0,0 +1,27 @@
|
||||
package io
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"io"
|
||||
)
|
||||
|
||||
func NewAesDecryptReader(key []byte, iv []byte, reader io.Reader) (io.Reader, error) {
|
||||
aesBlock, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aesMode := cipher.NewCBCDecrypter(aesBlock, iv)
|
||||
return NewCryptionReader(aesMode, reader), nil
|
||||
}
|
||||
|
||||
func NewAesEncryptWriter(key []byte, iv []byte, writer io.Writer) (io.Writer, error) {
|
||||
aesBlock, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aesMode := cipher.NewCBCEncrypter(aesBlock, iv)
|
||||
return NewCryptionWriter(aesMode, writer), nil
|
||||
}
|
@ -5,6 +5,8 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
v2net "github.com/v2ray/v2ray-core/net"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -128,7 +130,7 @@ func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
|
||||
// buffer[2] is a reserved field
|
||||
request.AddrType = buffer[3]
|
||||
switch request.AddrType {
|
||||
case 0x01:
|
||||
case AddrTypeIPv4:
|
||||
nBytes, err = reader.Read(request.IPv4[:])
|
||||
if err != nil {
|
||||
return
|
||||
@ -137,7 +139,7 @@ func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
|
||||
err = fmt.Errorf("Unable to read IPv4 address.")
|
||||
return
|
||||
}
|
||||
case 0x03:
|
||||
case AddrTypeDomain:
|
||||
buffer = make([]byte, 257)
|
||||
nBytes, err = reader.Read(buffer)
|
||||
if err != nil {
|
||||
@ -149,7 +151,7 @@ func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
|
||||
return
|
||||
}
|
||||
request.Domain = string(buffer[1 : domainLength+1])
|
||||
case 0x04:
|
||||
case AddrTypeIPv6:
|
||||
nBytes, err = reader.Read(request.IPv6[:])
|
||||
if err != nil {
|
||||
return
|
||||
@ -177,6 +179,19 @@ func ReadRequest(reader io.Reader) (request *Socks5Request, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (request *Socks5Request) Destination() v2net.VAddress {
|
||||
switch request.AddrType {
|
||||
case AddrTypeIPv4:
|
||||
return v2net.IPAddress(request.IPv4[:], request.Port)
|
||||
case AddrTypeIPv6:
|
||||
return v2net.IPAddress(request.IPv6[:], request.Port)
|
||||
case AddrTypeDomain:
|
||||
return v2net.DomainAddress(request.Domain, request.Port)
|
||||
default:
|
||||
panic("Unknown address type")
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
ErrorSuccess = byte(0x00)
|
||||
ErrorGeneralFailure = byte(0x01)
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/v2ray/v2ray-core"
|
||||
v2io "github.com/v2ray/v2ray-core/io"
|
||||
v2net "github.com/v2ray/v2ray-core/net"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -22,7 +23,7 @@ const (
|
||||
addrTypeIPv6 = byte(0x03)
|
||||
addrTypeDomain = byte(0x02)
|
||||
|
||||
vMessVersion = byte(0x01)
|
||||
Version = byte(0x01)
|
||||
)
|
||||
|
||||
var (
|
||||
@ -95,12 +96,25 @@ func (r *VMessRequest) targetAddressType() byte {
|
||||
return r[56]
|
||||
}
|
||||
|
||||
func (r *VMessRequest) Destination() v2net.VAddress {
|
||||
switch r.targetAddressType() {
|
||||
case addrTypeIPv4:
|
||||
fallthrough
|
||||
case addrTypeIPv6:
|
||||
return v2net.IPAddress(r.targetAddressBytes(), r.Port())
|
||||
case addrTypeDomain:
|
||||
return v2net.DomainAddress(r.TargetAddress(), r.Port())
|
||||
default:
|
||||
panic("Unpexected address type")
|
||||
}
|
||||
}
|
||||
|
||||
func (r *VMessRequest) TargetAddress() string {
|
||||
switch r.targetAddressType() {
|
||||
case addrTypeIPv4:
|
||||
return string(net.IPv4(r[57], r[58], r[59], r[60]))
|
||||
return net.IP(r[57:61]).String()
|
||||
case addrTypeIPv6:
|
||||
return string(net.IP(r[57:73]))
|
||||
return net.IP(r[57:73]).String()
|
||||
case addrTypeDomain:
|
||||
domainLength := int(r[57])
|
||||
return string(r[58 : 58+domainLength])
|
||||
@ -326,4 +340,10 @@ func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
type VMessOutput [4]byte
|
||||
type VMessResponse [4]byte
|
||||
|
||||
func NewVMessResponse(request *VMessRequest) *VMessResponse {
|
||||
response := new(VMessResponse)
|
||||
copy(response[:], request.ResponseHeader())
|
||||
return response
|
||||
}
|
||||
|
@ -5,24 +5,25 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/v2ray/v2ray-core"
|
||||
v2net "github.com/v2ray/v2ray-core/net"
|
||||
)
|
||||
|
||||
type VFreeConnection struct {
|
||||
network string
|
||||
address string
|
||||
vPoint *core.VPoint
|
||||
dest v2net.VAddress
|
||||
}
|
||||
|
||||
func NewVFreeConnection(network string, address string) *VFreeConnection {
|
||||
func NewVFreeConnection(vp *core.VPoint, dest v2net.VAddress) *VFreeConnection {
|
||||
conn := new(VFreeConnection)
|
||||
conn.network = network
|
||||
conn.address = address
|
||||
conn.vPoint = vp
|
||||
conn.dest = dest
|
||||
return conn
|
||||
}
|
||||
|
||||
func (vconn *VFreeConnection) Start(vRay core.OutboundVRay) error {
|
||||
input := vRay.OutboundInput()
|
||||
output := vRay.OutboundOutput()
|
||||
conn, err := net.Dial(vconn.network, vconn.address)
|
||||
conn, err := net.Dial("tcp", vconn.dest.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -2,8 +2,10 @@ package socks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/v2ray/v2ray-core"
|
||||
socksio "github.com/v2ray/v2ray-core/io/socks"
|
||||
)
|
||||
|
||||
@ -15,6 +17,13 @@ var (
|
||||
// SocksServer is a SOCKS 5 proxy server
|
||||
type SocksServer struct {
|
||||
accepting bool
|
||||
vPoint *core.VPoint
|
||||
}
|
||||
|
||||
func NewSocksServer(vp *core.VPoint) *SocksServer {
|
||||
server := new(SocksServer)
|
||||
server.vPoint = vp
|
||||
return server
|
||||
}
|
||||
|
||||
func (server *SocksServer) Listen(port uint8) error {
|
||||
@ -65,7 +74,43 @@ func (server *SocksServer) HandleConnection(connection net.Conn) error {
|
||||
return ErrorCommandNotSupported
|
||||
}
|
||||
|
||||
// TODO: establish connection with VNext
|
||||
ray := server.vPoint.NewInboundConnectionAccepted(request.Destination())
|
||||
input := ray.InboundInput()
|
||||
output := ray.InboundOutput()
|
||||
finish := make(chan bool, 2)
|
||||
|
||||
go server.dumpInput(connection, input, finish)
|
||||
go server.dumpOutput(connection, output, finish)
|
||||
server.waitForFinish(finish)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server *SocksServer) dumpInput(conn net.Conn, input chan<- []byte, finish chan<- bool) {
|
||||
for {
|
||||
buffer := make([]byte, 256)
|
||||
nBytes, err := conn.Read(buffer)
|
||||
if err == io.EOF {
|
||||
finish <- true
|
||||
break
|
||||
}
|
||||
input <- buffer[:nBytes]
|
||||
}
|
||||
}
|
||||
|
||||
func (server *SocksServer) dumpOutput(conn net.Conn, output <-chan []byte, finish chan<- bool) {
|
||||
for {
|
||||
buffer, open := <-output
|
||||
if !open {
|
||||
finish <- true
|
||||
break
|
||||
}
|
||||
conn.Write(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
func (server *SocksServer) waitForFinish(finish <-chan bool) {
|
||||
for i := 0; i < 2; i++ {
|
||||
<-finish
|
||||
}
|
||||
}
|
||||
|
12
net/socks/socksfactory.go
Normal file
12
net/socks/socksfactory.go
Normal file
@ -0,0 +1,12 @@
|
||||
package socks
|
||||
|
||||
import (
|
||||
"github.com/v2ray/v2ray-core"
|
||||
)
|
||||
|
||||
type SocksServerFactory struct {
|
||||
}
|
||||
|
||||
func (factory *SocksServerFactory) Create(vp *core.VPoint) *SocksServer {
|
||||
return NewSocksServer(vp)
|
||||
}
|
60
net/vdest.go
Normal file
60
net/vdest.go
Normal file
@ -0,0 +1,60 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
AddrTypeIP = byte(0x01)
|
||||
AddrTypeDomain = byte(0x03)
|
||||
)
|
||||
|
||||
type VAddress struct {
|
||||
Type byte
|
||||
IP net.IP
|
||||
Domain string
|
||||
Port uint16
|
||||
}
|
||||
|
||||
func IPAddress(ip []byte, port uint16) VAddress {
|
||||
// TODO: check IP length
|
||||
return VAddress{
|
||||
AddrTypeIP,
|
||||
net.IP(ip),
|
||||
"",
|
||||
port}
|
||||
}
|
||||
|
||||
func DomainAddress(domain string, port uint16) VAddress {
|
||||
return VAddress{
|
||||
AddrTypeDomain,
|
||||
nil,
|
||||
domain,
|
||||
port}
|
||||
}
|
||||
|
||||
func (addr VAddress) IsIPv4() bool {
|
||||
return addr.Type == AddrTypeIP && len(addr.IP) == net.IPv4len
|
||||
}
|
||||
|
||||
func (addr VAddress) IsIPv6() bool {
|
||||
return addr.Type == AddrTypeIP && len(addr.IP) == net.IPv6len
|
||||
}
|
||||
|
||||
func (addr VAddress) IsDomain() bool {
|
||||
return addr.Type == AddrTypeDomain
|
||||
}
|
||||
|
||||
func (addr VAddress) String() string {
|
||||
var host string
|
||||
switch addr.Type {
|
||||
case AddrTypeIP:
|
||||
host = addr.IP.String()
|
||||
case AddrTypeDomain:
|
||||
host = addr.Domain
|
||||
default:
|
||||
panic("Unknown Address Type " + strconv.Itoa(int(addr.Type)))
|
||||
}
|
||||
return host + ":" + strconv.Itoa(int(addr.Port))
|
||||
}
|
@ -1,17 +1,5 @@
|
||||
package vemss
|
||||
package vmess
|
||||
|
||||
import (
|
||||
"net"
|
||||
const (
|
||||
BufferSize = 256
|
||||
)
|
||||
|
||||
type VMessHandler struct {
|
||||
}
|
||||
|
||||
func (*VMessHandler) Listen(port uint8) error {
|
||||
_, err := net.Listen("tcp", ":"+string(port))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
119
net/vmess/vmessin.go
Normal file
119
net/vmess/vmessin.go
Normal file
@ -0,0 +1,119 @@
|
||||
package vmess
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/v2ray/v2ray-core"
|
||||
v2io "github.com/v2ray/v2ray-core/io"
|
||||
vmessio "github.com/v2ray/v2ray-core/io/vmess"
|
||||
)
|
||||
|
||||
type VMessInboundHandler struct {
|
||||
vPoint *core.VPoint
|
||||
accepting bool
|
||||
}
|
||||
|
||||
func NewVMessInboundHandler(vp *core.VPoint) *VMessInboundHandler {
|
||||
handler := new(VMessInboundHandler)
|
||||
handler.vPoint = vp
|
||||
return handler
|
||||
}
|
||||
|
||||
func (handler *VMessInboundHandler) Listen(port uint8) error {
|
||||
listener, err := net.Listen("tcp", ":"+string(port))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
handler.accepting = true
|
||||
go handler.AcceptConnections(listener)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (handler *VMessInboundHandler) AcceptConnections(listener net.Listener) error {
|
||||
for handler.accepting {
|
||||
connection, err := listener.Accept()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go handler.HandleConnection(connection)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (handler *VMessInboundHandler) HandleConnection(connection net.Conn) error {
|
||||
defer connection.Close()
|
||||
reader := vmessio.NewVMessRequestReader(handler.vPoint.UserSet)
|
||||
|
||||
request, err := reader.Read(connection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
response := vmessio.NewVMessResponse(request)
|
||||
connection.Write(response[:])
|
||||
|
||||
requestKey := request.RequestKey()
|
||||
requestIV := request.RequestIV()
|
||||
responseKey := md5.Sum(requestKey)
|
||||
responseIV := md5.Sum(requestIV)
|
||||
|
||||
requestReader, err := v2io.NewAesDecryptReader(requestKey, requestIV, connection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
responseWriter, err := v2io.NewAesEncryptWriter(responseKey[:], responseIV[:], connection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ray := handler.vPoint.NewInboundConnectionAccepted(request.Destination())
|
||||
input := ray.InboundInput()
|
||||
output := ray.InboundOutput()
|
||||
finish := make(chan bool, 2)
|
||||
|
||||
go handler.dumpInput(requestReader, input, finish)
|
||||
go handler.dumpOutput(responseWriter, output, finish)
|
||||
handler.waitForFinish(finish)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (handler *VMessInboundHandler) dumpInput(reader io.Reader, input chan<- []byte, finish chan<- bool) {
|
||||
for {
|
||||
buffer := make([]byte, BufferSize)
|
||||
nBytes, err := reader.Read(buffer)
|
||||
if err == io.EOF {
|
||||
finish <- true
|
||||
break
|
||||
}
|
||||
input <- buffer[:nBytes]
|
||||
}
|
||||
}
|
||||
|
||||
func (handler *VMessInboundHandler) dumpOutput(writer io.Writer, output <-chan []byte, finish chan<- bool) {
|
||||
for {
|
||||
buffer, open := <-output
|
||||
if !open {
|
||||
finish <- true
|
||||
break
|
||||
}
|
||||
writer.Write(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
func (handler *VMessInboundHandler) waitForFinish(finish <-chan bool) {
|
||||
for i := 0; i < 2; i++ {
|
||||
<-finish
|
||||
}
|
||||
}
|
||||
|
||||
type VMessInboundHandlerFactory struct {
|
||||
}
|
||||
|
||||
func (factory *VMessInboundHandlerFactory) Create(vp *core.VPoint) *VMessInboundHandler {
|
||||
return NewVMessInboundHandler(vp)
|
||||
}
|
133
net/vmess/vmessout.go
Normal file
133
net/vmess/vmessout.go
Normal file
@ -0,0 +1,133 @@
|
||||
package vmess
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
mrand "math/rand"
|
||||
"net"
|
||||
|
||||
"github.com/v2ray/v2ray-core"
|
||||
v2io "github.com/v2ray/v2ray-core/io"
|
||||
vmessio "github.com/v2ray/v2ray-core/io/vmess"
|
||||
v2net "github.com/v2ray/v2ray-core/net"
|
||||
)
|
||||
|
||||
type VMessOutboundHandler struct {
|
||||
vPoint *core.VPoint
|
||||
dest v2net.VAddress
|
||||
}
|
||||
|
||||
func NewVMessOutboundHandler(vp *core.VPoint, dest v2net.VAddress) *VMessOutboundHandler {
|
||||
handler := new(VMessOutboundHandler)
|
||||
handler.vPoint = vp
|
||||
handler.dest = dest
|
||||
return handler
|
||||
}
|
||||
|
||||
func (handler *VMessOutboundHandler) pickVNext() (v2net.VAddress, core.VUser) {
|
||||
vNextLen := len(handler.vPoint.Config.VNextList)
|
||||
if vNextLen == 0 {
|
||||
panic("Zero vNext is configured.")
|
||||
}
|
||||
vNextIndex := mrand.Intn(vNextLen)
|
||||
vNext := handler.vPoint.Config.VNextList[vNextIndex]
|
||||
vNextUserLen := len(vNext.Users)
|
||||
if vNextUserLen == 0 {
|
||||
panic("Zero User account.")
|
||||
}
|
||||
vNextUserIndex := mrand.Intn(vNextUserLen)
|
||||
vNextUser := vNext.Users[vNextUserIndex]
|
||||
return vNext.Address, vNextUser
|
||||
}
|
||||
|
||||
func (handler *VMessOutboundHandler) Start(ray core.OutboundVRay) error {
|
||||
vNextAddress, vNextUser := handler.pickVNext()
|
||||
|
||||
request := new(vmessio.VMessRequest)
|
||||
request.SetVersion(vmessio.Version)
|
||||
copy(request.UserHash(), vNextUser.Id.Hash([]byte("ASK")))
|
||||
rand.Read(request.RequestIV())
|
||||
rand.Read(request.RequestKey())
|
||||
rand.Read(request.ResponseHeader())
|
||||
request.SetCommand(byte(0x01))
|
||||
request.SetPort(handler.dest.Port)
|
||||
|
||||
address := handler.dest
|
||||
switch {
|
||||
case address.IsIPv4():
|
||||
request.SetIPv4(address.IP)
|
||||
case address.IsIPv6():
|
||||
request.SetIPv6(address.IP)
|
||||
case address.IsDomain():
|
||||
request.SetDomain(address.Domain)
|
||||
}
|
||||
|
||||
conn, err := net.Dial("tcp", vNextAddress.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
requestWriter := vmessio.NewVMessRequestWriter(handler.vPoint.UserSet)
|
||||
requestWriter.Write(conn, request)
|
||||
|
||||
requestKey := request.RequestKey()
|
||||
requestIV := request.RequestIV()
|
||||
responseKey := md5.Sum(requestKey)
|
||||
responseIV := md5.Sum(requestIV)
|
||||
|
||||
encryptRequestWriter, err := v2io.NewAesEncryptWriter(requestKey, requestIV, conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
responseReader, err := v2io.NewAesDecryptReader(responseKey[:], responseIV[:], conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
input := ray.OutboundInput()
|
||||
output := ray.OutboundOutput()
|
||||
finish := make(chan bool, 2)
|
||||
|
||||
go handler.dumpInput(encryptRequestWriter, input, finish)
|
||||
go handler.dumpOutput(responseReader, output, finish)
|
||||
handler.waitForFinish(finish)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (handler *VMessOutboundHandler) dumpOutput(reader io.Reader, output chan<- []byte, finish chan<- bool) {
|
||||
for {
|
||||
buffer := make([]byte, BufferSize)
|
||||
nBytes, err := reader.Read(buffer)
|
||||
if err == io.EOF {
|
||||
finish <- true
|
||||
break
|
||||
}
|
||||
output <- buffer[:nBytes]
|
||||
}
|
||||
}
|
||||
|
||||
func (handler *VMessOutboundHandler) dumpInput(writer io.Writer, input <-chan []byte, finish chan<- bool) {
|
||||
for {
|
||||
buffer, open := <-input
|
||||
if !open {
|
||||
finish <- true
|
||||
break
|
||||
}
|
||||
writer.Write(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
func (handler *VMessOutboundHandler) waitForFinish(finish <-chan bool) {
|
||||
for i := 0; i < 2; i++ {
|
||||
<-finish
|
||||
}
|
||||
}
|
||||
|
||||
type VMessOutboundHandlerFactory struct {
|
||||
}
|
||||
|
||||
func (factory *VMessOutboundHandlerFactory) Create(vp *core.VPoint, destination v2net.VAddress) *VMessOutboundHandler {
|
||||
return NewVMessOutboundHandler(vp, destination)
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
v2net "github.com/v2ray/v2ray-core/net"
|
||||
)
|
||||
|
||||
// VUser is the user account that is used for connection to a VPoint
|
||||
type VUser struct {
|
||||
Id VID // The ID of this VUser.
|
||||
@ -7,8 +11,8 @@ type VUser struct {
|
||||
|
||||
// VNext is the next VPoint server in the connection chain.
|
||||
type VNext struct {
|
||||
ServerAddress string // Address of VNext server, in the form of "IP:Port"
|
||||
User []VUser // User accounts for accessing VNext.
|
||||
Address v2net.VAddress // Address of VNext server
|
||||
Users []VUser // User accounts for accessing VNext.
|
||||
}
|
||||
|
||||
// VConfig is the config for VPoint server.
|
||||
|
46
vpoint.go
46
vpoint.go
@ -2,11 +2,14 @@ package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v2net "github.com/v2ray/v2ray-core/net"
|
||||
)
|
||||
|
||||
// VPoint is an single server in V2Ray system.
|
||||
type VPoint struct {
|
||||
config VConfig
|
||||
Config VConfig
|
||||
UserSet *VUserSet
|
||||
ichFactory InboundConnectionHandlerFactory
|
||||
ochFactory OutboundConnectionHandlerFactory
|
||||
}
|
||||
@ -15,7 +18,13 @@ type VPoint struct {
|
||||
// The server is not started at this point.
|
||||
func NewVPoint(config *VConfig) (*VPoint, error) {
|
||||
var vpoint = new(VPoint)
|
||||
vpoint.config = *config
|
||||
vpoint.Config = *config
|
||||
vpoint.UserSet = NewVUserSet()
|
||||
|
||||
for _, user := range vpoint.Config.AllowedClients {
|
||||
vpoint.UserSet.AddUser(user)
|
||||
}
|
||||
|
||||
return vpoint, nil
|
||||
}
|
||||
|
||||
@ -28,23 +37,46 @@ type InboundConnectionHandler interface {
|
||||
}
|
||||
|
||||
type OutboundConnectionHandlerFactory interface {
|
||||
Create(vPoint *VPoint) (OutboundConnectionHandler, error)
|
||||
Create(vPoint *VPoint, dest v2net.VAddress) (OutboundConnectionHandler, error)
|
||||
}
|
||||
|
||||
type OutboundConnectionHandler interface {
|
||||
Start(vray *OutboundVRay) error
|
||||
Start(vray OutboundVRay) error
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (vp *VPoint) Start() error {
|
||||
if vp.config.Port <= 0 {
|
||||
return fmt.Errorf("Invalid port %d", vp.config.Port)
|
||||
if vp.Config.Port <= 0 {
|
||||
return fmt.Errorf("Invalid port %d", vp.Config.Port)
|
||||
}
|
||||
inboundConnectionHandler, err := vp.ichFactory.Create(vp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = inboundConnectionHandler.Listen(vp.config.Port)
|
||||
err = inboundConnectionHandler.Listen(vp.Config.Port)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vp *VPoint) NewInboundConnectionAccepted(destination v2net.VAddress) InboundVRay {
|
||||
/*
|
||||
vNextLen := len(vp.Config.VNextList)
|
||||
if vNextLen > 0 {
|
||||
vNextIndex := rand.Intn(vNextLen)
|
||||
vNext := vp.Config.VNextList[vNextIndex]
|
||||
vNextUser := dest.User
|
||||
vNextUserLen := len(vNext.Users)
|
||||
if vNextUserLen > 0 {
|
||||
vNextUserIndex = rand.Intn(vNextUserLen)
|
||||
vNextUser = vNext.Users[vNextUserIndex]
|
||||
}
|
||||
newDest := VDestination{"tcp", vNext.ServerAddress, vNextUser}
|
||||
dest = newDest
|
||||
}*/
|
||||
|
||||
ray := NewVRay()
|
||||
// TODO: handle error
|
||||
och, _ := vp.ochFactory.Create(vp, destination)
|
||||
_ = och.Start(ray)
|
||||
return ray
|
||||
}
|
||||
|
17
vray.go
17
vray.go
@ -5,11 +5,8 @@ type VRay struct {
|
||||
Output chan []byte
|
||||
}
|
||||
|
||||
func NewVRay() *VRay {
|
||||
ray := new(VRay)
|
||||
ray.Input = make(chan []byte, 128)
|
||||
ray.Output = make(chan []byte, 128)
|
||||
return ray
|
||||
func NewVRay() VRay {
|
||||
return VRay{make(chan []byte, 128), make(chan []byte, 128)}
|
||||
}
|
||||
|
||||
type OutboundVRay interface {
|
||||
@ -19,21 +16,21 @@ type OutboundVRay interface {
|
||||
|
||||
type InboundVRay interface {
|
||||
InboundInput() chan<- []byte
|
||||
OutboundOutput() <-chan []byte
|
||||
InboundOutput() <-chan []byte
|
||||
}
|
||||
|
||||
func (ray *VRay) OutboundInput() <-chan []byte {
|
||||
func (ray VRay) OutboundInput() <-chan []byte {
|
||||
return ray.Input
|
||||
}
|
||||
|
||||
func (ray *VRay) OutboundOutput() chan<- []byte {
|
||||
func (ray VRay) OutboundOutput() chan<- []byte {
|
||||
return ray.Output
|
||||
}
|
||||
|
||||
func (ray *VRay) InboundInput() chan<- []byte {
|
||||
func (ray VRay) InboundInput() chan<- []byte {
|
||||
return ray.Input
|
||||
}
|
||||
|
||||
func (ray *VRay) InboundOutput() <-chan []byte {
|
||||
func (ray VRay) InboundOutput() <-chan []byte {
|
||||
return ray.Output
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user