Selaa lähdekoodia

receiver manager

v2ray 10 vuotta sitten
vanhempi
commit
06f9b65ec4

+ 26 - 11
proxy/vmess/config/json/outbound.go

@@ -11,22 +11,25 @@ import (
 	vmessconfig "github.com/v2ray/v2ray-core/proxy/vmess/config"
 )
 
-type RawConfigTarget struct {
-	Address string        `json:"address"`
-	Port    v2net.Port    `json:"port"`
-	Users   []*ConfigUser `json:"users"`
-}
-
 type ConfigTarget struct {
 	Address v2net.Address
 	Users   []*ConfigUser
 }
 
 func (t *ConfigTarget) UnmarshalJSON(data []byte) error {
+	type RawConfigTarget struct {
+		Address string        `json:"address"`
+		Port    v2net.Port    `json:"port"`
+		Users   []*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 proxyconfig.BadConfiguration
+	}
 	t.Users = rawConfig.Users
 	ip := net.ParseIP(rawConfig.Address)
 	if ip == nil {
@@ -41,16 +44,28 @@ type Outbound struct {
 	TargetList []*ConfigTarget `json:"vnext"`
 }
 
-func (o *Outbound) Targets() []*vmessconfig.OutboundTarget {
-	targets := make([]*vmessconfig.OutboundTarget, 0, 2*len(o.TargetList))
+func (this *Outbound) UnmarshallJSON(data []byte) error {
+	err := json.Unmarshal(data, this)
+	if err != nil {
+		return err
+	}
+	if len(this.TargetList) == 0 {
+		log.Error("0 VMess receiver configured.")
+		return proxyconfig.BadConfiguration
+	}
+	return nil
+}
+
+func (o *Outbound) Receivers() []*vmessconfig.Receiver {
+	targets := make([]*vmessconfig.Receiver, 0, 2*len(o.TargetList))
 	for _, rawTarget := range o.TargetList {
 		users := make([]vmessconfig.User, 0, len(rawTarget.Users))
 		for _, rawUser := range rawTarget.Users {
 			users = append(users, rawUser)
 		}
-		targets = append(targets, &vmessconfig.OutboundTarget{
-			Destination: v2net.NewTCPDestination(rawTarget.Address),
-			Accounts:    users,
+		targets = append(targets, &vmessconfig.Receiver{
+			Address:  rawTarget.Address,
+			Accounts: users,
 		})
 	}
 	return targets

+ 4 - 4
proxy/vmess/config/outbound.go

@@ -4,11 +4,11 @@ import (
 	v2net "github.com/v2ray/v2ray-core/common/net"
 )
 
-type OutboundTarget struct {
-	Destination v2net.Destination
-	Accounts    []User
+type Receiver struct {
+	Address  v2net.Address
+	Accounts []User
 }
 
 type Outbound interface {
-	Targets() []*OutboundTarget
+	Receivers() []*Receiver
 }

+ 8 - 37
proxy/vmess/outbound/outbound.go

@@ -3,7 +3,6 @@ package outbound
 import (
 	"crypto/md5"
 	"crypto/rand"
-	mrand "math/rand"
 	"net"
 	"sync"
 
@@ -19,41 +18,11 @@ import (
 )
 
 type VMessOutboundHandler struct {
-	vNextList []*config.OutboundTarget
-}
-
-func NewVMessOutboundHandler(vNextList []*config.OutboundTarget) *VMessOutboundHandler {
-	return &VMessOutboundHandler{
-		vNextList: vNextList,
-	}
-}
-
-func pickVNext(serverList []*config.OutboundTarget) (v2net.Destination, config.User) {
-	vNextLen := len(serverList)
-	if vNextLen == 0 {
-		panic("VMessOut: Zero vNext is configured.")
-	}
-	vNextIndex := 0
-	if vNextLen > 1 {
-		vNextIndex = mrand.Intn(vNextLen)
-	}
-
-	vNext := serverList[vNextIndex]
-	vNextUserLen := len(vNext.Accounts)
-	if vNextUserLen == 0 {
-		panic("VMessOut: Zero User account.")
-	}
-	vNextUserIndex := 0
-	if vNextUserLen > 1 {
-		vNextUserIndex = mrand.Intn(vNextUserLen)
-	}
-	vNextUser := vNext.Accounts[vNextUserIndex]
-	return vNext.Destination, vNextUser
+	receiverManager *ReceiverManager
 }
 
 func (this *VMessOutboundHandler) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error {
-	vNextList := this.vNextList
-	vNextAddress, vNextUser := pickVNext(vNextList)
+	vNextAddress, vNextUser := this.receiverManager.PickReceiver()
 
 	command := protocol.CmdTCP
 	if firstPacket.Destination().IsUDP() {
@@ -76,8 +45,8 @@ func (this *VMessOutboundHandler) Dispatch(firstPacket v2net.Packet, ray ray.Out
 	return startCommunicate(request, vNextAddress, ray, firstPacket)
 }
 
-func startCommunicate(request *protocol.VMessRequest, dest v2net.Destination, ray ray.OutboundRay, firstPacket v2net.Packet) error {
-	conn, err := net.Dial(dest.Network(), dest.Address().String())
+func startCommunicate(request *protocol.VMessRequest, dest v2net.Address, ray ray.OutboundRay, firstPacket v2net.Packet) error {
+	conn, err := net.Dial("tcp", dest.String())
 	if err != nil {
 		log.Error("Failed to open %s: %v", dest.String(), err)
 		if ray != nil {
@@ -96,7 +65,7 @@ func startCommunicate(request *protocol.VMessRequest, dest v2net.Destination, ra
 	responseFinish.Lock()
 
 	go handleRequest(conn, request, firstPacket, input, &requestFinish)
-	go handleResponse(conn, request, output, &responseFinish, dest.IsUDP())
+	go handleResponse(conn, request, output, &responseFinish, (request.Command == protocol.CmdUDP))
 
 	requestFinish.Lock()
 	if tcpConn, ok := conn.(*net.TCPConn); ok {
@@ -207,7 +176,9 @@ type VMessOutboundHandlerFactory struct {
 
 func (this *VMessOutboundHandlerFactory) Create(rawConfig interface{}) (connhandler.OutboundConnectionHandler, error) {
 	vOutConfig := rawConfig.(config.Outbound)
-	return NewVMessOutboundHandler(vOutConfig.Targets()), nil
+	return &VMessOutboundHandler{
+		receiverManager: NewReceiverManager(vOutConfig.Receivers()),
+	}, nil
 }
 
 func init() {

+ 36 - 0
proxy/vmess/outbound/receiver_manager.go

@@ -0,0 +1,36 @@
+package outbound
+
+import (
+	"math/rand"
+
+	v2net "github.com/v2ray/v2ray-core/common/net"
+	"github.com/v2ray/v2ray-core/proxy/vmess/config"
+)
+
+type ReceiverManager struct {
+	receivers []*config.Receiver
+}
+
+func NewReceiverManager(receivers []*config.Receiver) *ReceiverManager {
+	return &ReceiverManager{
+		receivers: receivers,
+	}
+}
+
+func (this *ReceiverManager) PickReceiver() (v2net.Address, config.User) {
+	receiverLen := len(this.receivers)
+	receiverIdx := 0
+	if receiverLen > 1 {
+		receiverIdx = rand.Intn(receiverLen)
+	}
+
+	receiver := this.receivers[receiverIdx]
+
+	userLen := len(receiver.Accounts)
+	userIdx := 0
+	if userLen > 1 {
+		userIdx = rand.Intn(userLen)
+	}
+	user := receiver.Accounts[userIdx]
+	return receiver.Address, user
+}