mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 01:57:12 -05:00
Refactor vmess internal struct for better readability
This commit is contained in:
parent
8a6b07ba61
commit
791ac780f0
@ -11,7 +11,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
_ "log"
|
_ "log"
|
||||||
mrand "math/rand"
|
mrand "math/rand"
|
||||||
"net"
|
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core"
|
"github.com/v2ray/v2ray-core"
|
||||||
v2io "github.com/v2ray/v2ray-core/io"
|
v2io "github.com/v2ray/v2ray-core/io"
|
||||||
@ -33,127 +32,15 @@ var (
|
|||||||
// VMessRequest implements the request message of VMess protocol. It only contains
|
// VMessRequest implements the request message of VMess protocol. It only contains
|
||||||
// the header of a request message. The data part will be handled by conection
|
// the header of a request message. The data part will be handled by conection
|
||||||
// handler directly, in favor of data streaming.
|
// handler directly, in favor of data streaming.
|
||||||
// 1 Version
|
|
||||||
// 16 UserHash
|
|
||||||
// 16 Request IV
|
|
||||||
// 16 Request Key
|
|
||||||
// 4 Response Header
|
|
||||||
// 1 Command
|
|
||||||
// 2 Port
|
|
||||||
// 1 Address Type
|
|
||||||
// 256 Target Address
|
|
||||||
|
|
||||||
type VMessRequest [312]byte
|
type VMessRequest struct {
|
||||||
|
Version byte
|
||||||
func (r *VMessRequest) Version() byte {
|
UserId core.VID
|
||||||
return r[0]
|
RequestIV [16]byte
|
||||||
}
|
RequestKey [16]byte
|
||||||
|
ResponseHeader [4]byte
|
||||||
func (r *VMessRequest) SetVersion(version byte) *VMessRequest {
|
Command byte
|
||||||
r[0] = version
|
Address v2net.VAddress
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) UserHash() []byte {
|
|
||||||
return r[1:17]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) RequestIV() []byte {
|
|
||||||
return r[17:33]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) RequestKey() []byte {
|
|
||||||
return r[33:49]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) ResponseHeader() []byte {
|
|
||||||
return r[49:53]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) Command() byte {
|
|
||||||
return r[53]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) SetCommand(command byte) *VMessRequest {
|
|
||||||
r[53] = command
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) Port() uint16 {
|
|
||||||
return binary.BigEndian.Uint16(r.portBytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) portBytes() []byte {
|
|
||||||
return r[54:56]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) SetPort(port uint16) *VMessRequest {
|
|
||||||
binary.BigEndian.PutUint16(r.portBytes(), port)
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
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 net.IP(r[57:61]).String()
|
|
||||||
case addrTypeIPv6:
|
|
||||||
return net.IP(r[57:73]).String()
|
|
||||||
case addrTypeDomain:
|
|
||||||
domainLength := int(r[57])
|
|
||||||
return string(r[58 : 58+domainLength])
|
|
||||||
default:
|
|
||||||
panic("Unexpected address type")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) targetAddressBytes() []byte {
|
|
||||||
switch r.targetAddressType() {
|
|
||||||
case addrTypeIPv4:
|
|
||||||
return r[57:61]
|
|
||||||
case addrTypeIPv6:
|
|
||||||
return r[57:73]
|
|
||||||
case addrTypeDomain:
|
|
||||||
domainLength := int(r[57])
|
|
||||||
return r[57 : 58+domainLength]
|
|
||||||
default:
|
|
||||||
panic("Unexpected address type")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) SetIPv4(ipv4 []byte) *VMessRequest {
|
|
||||||
r[56] = addrTypeIPv4
|
|
||||||
copy(r[57:], ipv4)
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) SetIPv6(ipv6 []byte) *VMessRequest {
|
|
||||||
r[56] = addrTypeIPv6
|
|
||||||
copy(r[57:], ipv6)
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *VMessRequest) SetDomain(domain string) *VMessRequest {
|
|
||||||
r[56] = addrTypeDomain
|
|
||||||
r[57] = byte(len(domain))
|
|
||||||
copy(r[58:], []byte(domain))
|
|
||||||
return r
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type VMessRequestReader struct {
|
type VMessRequestReader struct {
|
||||||
@ -169,26 +56,30 @@ func NewVMessRequestReader(vUserSet *core.VUserSet) *VMessRequestReader {
|
|||||||
func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
||||||
request := new(VMessRequest)
|
request := new(VMessRequest)
|
||||||
|
|
||||||
nBytes, err := reader.Read(request[0:17] /* version + user hash */)
|
buffer := make([]byte, 256)
|
||||||
|
nBytes, err := reader.Read(buffer[0:1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if nBytes != 17 {
|
// TODO: verify version number
|
||||||
err = fmt.Errorf("Unexpected length of header %d", nBytes)
|
request.Version = buffer[0]
|
||||||
|
|
||||||
|
nBytes, err = reader.Read(buffer[:len(request.UserId)])
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// TODO: verify version number
|
|
||||||
userId, valid := r.vUserSet.IsValidUserId(request.UserHash())
|
userId, valid := r.vUserSet.IsValidUserId(buffer[:nBytes])
|
||||||
if !valid {
|
if !valid {
|
||||||
return nil, ErrorInvalidUser
|
return nil, ErrorInvalidUser
|
||||||
}
|
}
|
||||||
|
request.UserId = *userId
|
||||||
|
|
||||||
decryptor, err := NewDecryptionReader(reader, userId.Hash([]byte("PWD")), make([]byte, blockSize))
|
decryptor, err := NewDecryptionReader(reader, userId.Hash([]byte("PWD")), make([]byte, blockSize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer := make([]byte, 300)
|
|
||||||
nBytes, err = decryptor.Read(buffer[0:1])
|
nBytes, err = decryptor.Read(buffer[0:1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -204,15 +95,15 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check number of bytes returned
|
// TODO: check number of bytes returned
|
||||||
_, err = decryptor.Read(request.RequestIV())
|
_, err = decryptor.Read(request.RequestIV[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = decryptor.Read(request.RequestKey())
|
_, err = decryptor.Read(request.RequestKey[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = decryptor.Read(request.ResponseHeader())
|
_, err = decryptor.Read(request.ResponseHeader[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -220,13 +111,13 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
request.SetCommand(buffer[0])
|
request.Command = buffer[0]
|
||||||
|
|
||||||
_, err = decryptor.Read(buffer[0:2])
|
_, err = decryptor.Read(buffer[0:2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
request.SetPort(binary.BigEndian.Uint16(buffer[0:2]))
|
port := binary.BigEndian.Uint16(buffer[0:2])
|
||||||
|
|
||||||
_, err = decryptor.Read(buffer[0:1])
|
_, err = decryptor.Read(buffer[0:1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -238,13 +129,13 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
request.SetIPv4(buffer[1:5])
|
request.Address = v2net.IPAddress(buffer[1:5], port)
|
||||||
case addrTypeIPv6:
|
case addrTypeIPv6:
|
||||||
_, err = decryptor.Read(buffer[1:17])
|
_, err = decryptor.Read(buffer[1:17])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
request.SetIPv6(buffer[1:17])
|
request.Address = v2net.IPAddress(buffer[1:17], port)
|
||||||
case addrTypeDomain:
|
case addrTypeDomain:
|
||||||
_, err = decryptor.Read(buffer[1:2])
|
_, err = decryptor.Read(buffer[1:2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -255,7 +146,7 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
request.SetDomain(string(buffer[2 : 2+domainLength]))
|
request.Address = v2net.DomainAddress(string(buffer[2:2+domainLength]), port)
|
||||||
}
|
}
|
||||||
_, err = decryptor.Read(buffer[0:1])
|
_, err = decryptor.Read(buffer[0:1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -271,19 +162,17 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VMessRequestWriter struct {
|
type VMessRequestWriter struct {
|
||||||
vUserSet *core.VUserSet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVMessRequestWriter(vUserSet *core.VUserSet) *VMessRequestWriter {
|
func NewVMessRequestWriter() *VMessRequestWriter {
|
||||||
writer := new(VMessRequestWriter)
|
writer := new(VMessRequestWriter)
|
||||||
writer.vUserSet = vUserSet
|
|
||||||
return writer
|
return writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) error {
|
func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) error {
|
||||||
buffer := make([]byte, 0, 300)
|
buffer := make([]byte, 0, 300)
|
||||||
buffer = append(buffer, request.Version())
|
buffer = append(buffer, request.Version)
|
||||||
buffer = append(buffer, request.UserHash()...)
|
buffer = append(buffer, request.UserId.Hash([]byte("ASK"))...)
|
||||||
|
|
||||||
encryptionBegin := len(buffer)
|
encryptionBegin := len(buffer)
|
||||||
|
|
||||||
@ -296,13 +185,27 @@ func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) erro
|
|||||||
buffer = append(buffer, byte(randomLength))
|
buffer = append(buffer, byte(randomLength))
|
||||||
buffer = append(buffer, randomContent...)
|
buffer = append(buffer, randomContent...)
|
||||||
|
|
||||||
buffer = append(buffer, request.RequestIV()...)
|
buffer = append(buffer, request.RequestIV[:]...)
|
||||||
buffer = append(buffer, request.RequestKey()...)
|
buffer = append(buffer, request.RequestKey[:]...)
|
||||||
buffer = append(buffer, request.ResponseHeader()...)
|
buffer = append(buffer, request.ResponseHeader[:]...)
|
||||||
buffer = append(buffer, request.Command())
|
buffer = append(buffer, request.Command)
|
||||||
buffer = append(buffer, request.portBytes()...)
|
|
||||||
buffer = append(buffer, request.targetAddressType())
|
portBytes := make([]byte, 2)
|
||||||
buffer = append(buffer, request.targetAddressBytes()...)
|
binary.BigEndian.PutUint16(portBytes, request.Address.Port)
|
||||||
|
buffer = append(buffer, portBytes...)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case request.Address.IsIPv4():
|
||||||
|
buffer = append(buffer, addrTypeIPv4)
|
||||||
|
buffer = append(buffer, request.Address.IP...)
|
||||||
|
case request.Address.IsIPv6():
|
||||||
|
buffer = append(buffer, addrTypeIPv6)
|
||||||
|
buffer = append(buffer, request.Address.IP...)
|
||||||
|
case request.Address.IsDomain():
|
||||||
|
buffer = append(buffer, addrTypeDomain)
|
||||||
|
buffer = append(buffer, byte(len(request.Address.Domain)))
|
||||||
|
buffer = append(buffer, []byte(request.Address.Domain)...)
|
||||||
|
}
|
||||||
|
|
||||||
paddingLength := blockSize - 1 - (len(buffer)-encryptionBegin)%blockSize
|
paddingLength := blockSize - 1 - (len(buffer)-encryptionBegin)%blockSize
|
||||||
if paddingLength == 0 {
|
if paddingLength == 0 {
|
||||||
@ -317,11 +220,7 @@ func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) erro
|
|||||||
buffer = append(buffer, paddingBuffer...)
|
buffer = append(buffer, paddingBuffer...)
|
||||||
encryptionEnd := len(buffer)
|
encryptionEnd := len(buffer)
|
||||||
|
|
||||||
userId, valid := w.vUserSet.IsValidUserId(request.UserHash())
|
aesCipher, err := aes.NewCipher(request.UserId.Hash([]byte("PWD")))
|
||||||
if !valid {
|
|
||||||
return ErrorInvalidUser
|
|
||||||
}
|
|
||||||
aesCipher, err := aes.NewCipher(userId.Hash([]byte("PWD")))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -344,6 +243,6 @@ type VMessResponse [4]byte
|
|||||||
|
|
||||||
func NewVMessResponse(request *VMessRequest) *VMessResponse {
|
func NewVMessResponse(request *VMessRequest) *VMessResponse {
|
||||||
response := new(VMessResponse)
|
response := new(VMessResponse)
|
||||||
copy(response[:], request.ResponseHeader())
|
copy(response[:], request.ResponseHeader[:])
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,13 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core"
|
"github.com/v2ray/v2ray-core"
|
||||||
|
v2net "github.com/v2ray/v2ray-core/net"
|
||||||
|
"github.com/v2ray/v2ray-core/testing/unit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestVMessSerialization(t *testing.T) {
|
func TestVMessSerialization(t *testing.T) {
|
||||||
|
assert := unit.Assert(t)
|
||||||
|
|
||||||
userId, err := core.UUIDToVID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
userId, err := core.UUIDToVID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -18,31 +22,29 @@ func TestVMessSerialization(t *testing.T) {
|
|||||||
userSet.AddUser(core.VUser{userId})
|
userSet.AddUser(core.VUser{userId})
|
||||||
|
|
||||||
request := new(VMessRequest)
|
request := new(VMessRequest)
|
||||||
request.SetVersion(byte(0x01))
|
request.Version = byte(0x01)
|
||||||
userHash := userId.Hash([]byte("ASK"))
|
request.UserId = userId
|
||||||
copy(request.UserHash(), userHash)
|
|
||||||
|
|
||||||
_, err = rand.Read(request.RequestIV())
|
_, err = rand.Read(request.RequestIV[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = rand.Read(request.RequestKey())
|
_, err = rand.Read(request.RequestKey[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = rand.Read(request.ResponseHeader())
|
_, err = rand.Read(request.ResponseHeader[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
request.SetCommand(byte(0x01))
|
request.Command = byte(0x01)
|
||||||
request.SetPort(80)
|
request.Address = v2net.DomainAddress("v2ray.com", 80)
|
||||||
request.SetDomain("v2ray.com")
|
|
||||||
|
|
||||||
buffer := bytes.NewBuffer(make([]byte, 0, 300))
|
buffer := bytes.NewBuffer(make([]byte, 0, 300))
|
||||||
requestWriter := NewVMessRequestWriter(userSet)
|
requestWriter := NewVMessRequestWriter()
|
||||||
err = requestWriter.Write(buffer, request)
|
err = requestWriter.Write(buffer, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -54,35 +56,11 @@ func TestVMessSerialization(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if actualRequest.Version() != byte(0x01) {
|
assert.Byte(actualRequest.Version).Named("Version").Equals(byte(0x01))
|
||||||
t.Errorf("Expected Version 1, but got %d", actualRequest.Version())
|
assert.Bytes(actualRequest.UserId[:]).Named("UserId").Equals(request.UserId[:])
|
||||||
}
|
assert.Bytes(actualRequest.RequestIV[:]).Named("RequestIV").Equals(request.RequestIV[:])
|
||||||
|
assert.Bytes(actualRequest.RequestKey[:]).Named("RequestKey").Equals(request.RequestKey[:])
|
||||||
if !bytes.Equal(request.UserHash(), actualRequest.UserHash()) {
|
assert.Bytes(actualRequest.ResponseHeader[:]).Named("ResponseHeader").Equals(request.ResponseHeader[:])
|
||||||
t.Errorf("Expected user hash %v, but got %v", request.UserHash(), actualRequest.UserHash())
|
assert.Byte(actualRequest.Command).Named("Command").Equals(request.Command)
|
||||||
}
|
assert.String(actualRequest.Address.String()).Named("Address").Equals(request.Address.String())
|
||||||
|
|
||||||
if !bytes.Equal(request.RequestIV(), actualRequest.RequestIV()) {
|
|
||||||
t.Errorf("Expected request IV %v, but got %v", request.RequestIV(), actualRequest.RequestIV())
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(request.RequestKey(), actualRequest.RequestKey()) {
|
|
||||||
t.Errorf("Expected request Key %v, but got %v", request.RequestKey(), actualRequest.RequestKey())
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(request.ResponseHeader(), actualRequest.ResponseHeader()) {
|
|
||||||
t.Errorf("Expected response header %v, but got %v", request.ResponseHeader(), actualRequest.ResponseHeader())
|
|
||||||
}
|
|
||||||
|
|
||||||
if actualRequest.Command() != byte(0x01) {
|
|
||||||
t.Errorf("Expected command 1, but got %d", actualRequest.Command())
|
|
||||||
}
|
|
||||||
|
|
||||||
if actualRequest.Port() != 80 {
|
|
||||||
t.Errorf("Expected port 80, but got %d", actualRequest.Port())
|
|
||||||
}
|
|
||||||
|
|
||||||
if actualRequest.TargetAddress() != "v2ray.com" {
|
|
||||||
t.Errorf("Expected target address v2ray.com, but got %s", actualRequest.TargetAddress())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
45
log/log.go
Normal file
45
log/log.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DebugLevel = LogLevel(0)
|
||||||
|
InfoLevel = LogLevel(1)
|
||||||
|
WarningLevel = LogLevel(2)
|
||||||
|
ErrorLevel = LogLevel(3)
|
||||||
|
)
|
||||||
|
|
||||||
|
var logLevel = WarningLevel
|
||||||
|
|
||||||
|
type LogLevel int
|
||||||
|
|
||||||
|
func SetLogLevel(level LogLevel) {
|
||||||
|
logLevel = level
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeLog(data string, level LogLevel) {
|
||||||
|
if level < logLevel {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Print(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Info(format string, v ...interface{}) {
|
||||||
|
data := fmt.Sprintf(format, v)
|
||||||
|
writeLog("[Info]"+data, InfoLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Warning(format string, v ...interface{}) {
|
||||||
|
data := fmt.Sprintf(format, v)
|
||||||
|
writeLog("[Warning]"+data, WarningLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Error(format string, v ...interface{}) error {
|
||||||
|
data := fmt.Sprintf(format, v)
|
||||||
|
writeLog("[Error]"+data, ErrorLevel)
|
||||||
|
return errors.New(data)
|
||||||
|
}
|
@ -12,12 +12,14 @@ import (
|
|||||||
|
|
||||||
type VMessInboundHandler struct {
|
type VMessInboundHandler struct {
|
||||||
vPoint *core.VPoint
|
vPoint *core.VPoint
|
||||||
|
clients *core.VUserSet
|
||||||
accepting bool
|
accepting bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVMessInboundHandler(vp *core.VPoint) *VMessInboundHandler {
|
func NewVMessInboundHandler(vp *core.VPoint, clients *core.VUserSet) *VMessInboundHandler {
|
||||||
handler := new(VMessInboundHandler)
|
handler := new(VMessInboundHandler)
|
||||||
handler.vPoint = vp
|
handler.vPoint = vp
|
||||||
|
handler.clients = clients
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +47,7 @@ func (handler *VMessInboundHandler) AcceptConnections(listener net.Listener) err
|
|||||||
|
|
||||||
func (handler *VMessInboundHandler) HandleConnection(connection net.Conn) error {
|
func (handler *VMessInboundHandler) HandleConnection(connection net.Conn) error {
|
||||||
defer connection.Close()
|
defer connection.Close()
|
||||||
reader := vmessio.NewVMessRequestReader(handler.vPoint.UserSet)
|
reader := vmessio.NewVMessRequestReader(handler.clients)
|
||||||
|
|
||||||
request, err := reader.Read(connection)
|
request, err := reader.Read(connection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -55,8 +57,8 @@ func (handler *VMessInboundHandler) HandleConnection(connection net.Conn) error
|
|||||||
response := vmessio.NewVMessResponse(request)
|
response := vmessio.NewVMessResponse(request)
|
||||||
connection.Write(response[:])
|
connection.Write(response[:])
|
||||||
|
|
||||||
requestKey := request.RequestKey()
|
requestKey := request.RequestKey[:]
|
||||||
requestIV := request.RequestIV()
|
requestIV := request.RequestIV[:]
|
||||||
responseKey := md5.Sum(requestKey)
|
responseKey := md5.Sum(requestKey)
|
||||||
responseIV := md5.Sum(requestIV)
|
responseIV := md5.Sum(requestIV)
|
||||||
|
|
||||||
@ -70,7 +72,7 @@ func (handler *VMessInboundHandler) HandleConnection(connection net.Conn) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ray := handler.vPoint.NewInboundConnectionAccepted(request.Destination())
|
ray := handler.vPoint.NewInboundConnectionAccepted(request.Address)
|
||||||
input := ray.InboundInput()
|
input := ray.InboundInput()
|
||||||
output := ray.InboundOutput()
|
output := ray.InboundOutput()
|
||||||
finish := make(chan bool, 2)
|
finish := make(chan bool, 2)
|
||||||
@ -112,8 +114,18 @@ func (handler *VMessInboundHandler) waitForFinish(finish <-chan bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VMessInboundHandlerFactory struct {
|
type VMessInboundHandlerFactory struct {
|
||||||
|
allowedClients *core.VUserSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewVMessInboundHandlerFactory(clients []core.VUser) *VMessInboundHandlerFactory {
|
||||||
|
factory := new(VMessInboundHandlerFactory)
|
||||||
|
factory.allowedClients = core.NewVUserSet()
|
||||||
|
for _, user := range clients {
|
||||||
|
factory.allowedClients.AddUser(user)
|
||||||
|
}
|
||||||
|
return factory
|
||||||
}
|
}
|
||||||
|
|
||||||
func (factory *VMessInboundHandlerFactory) Create(vp *core.VPoint) *VMessInboundHandler {
|
func (factory *VMessInboundHandlerFactory) Create(vp *core.VPoint) *VMessInboundHandler {
|
||||||
return NewVMessInboundHandler(vp)
|
return NewVMessInboundHandler(vp, factory.allowedClients)
|
||||||
}
|
}
|
||||||
|
@ -45,23 +45,13 @@ func (handler *VMessOutboundHandler) Start(ray core.OutboundVRay) error {
|
|||||||
vNextAddress, vNextUser := handler.pickVNext()
|
vNextAddress, vNextUser := handler.pickVNext()
|
||||||
|
|
||||||
request := new(vmessio.VMessRequest)
|
request := new(vmessio.VMessRequest)
|
||||||
request.SetVersion(vmessio.Version)
|
request.Version = vmessio.Version
|
||||||
copy(request.UserHash(), vNextUser.Id.Hash([]byte("ASK")))
|
request.UserId = vNextUser.Id
|
||||||
rand.Read(request.RequestIV())
|
rand.Read(request.RequestIV[:])
|
||||||
rand.Read(request.RequestKey())
|
rand.Read(request.RequestKey[:])
|
||||||
rand.Read(request.ResponseHeader())
|
rand.Read(request.ResponseHeader[:])
|
||||||
request.SetCommand(byte(0x01))
|
request.Command = byte(0x01)
|
||||||
request.SetPort(handler.dest.Port)
|
request.Address = handler.dest
|
||||||
|
|
||||||
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())
|
conn, err := net.Dial("tcp", vNextAddress.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -69,11 +59,11 @@ func (handler *VMessOutboundHandler) Start(ray core.OutboundVRay) error {
|
|||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
requestWriter := vmessio.NewVMessRequestWriter(handler.vPoint.UserSet)
|
requestWriter := vmessio.NewVMessRequestWriter()
|
||||||
requestWriter.Write(conn, request)
|
requestWriter.Write(conn, request)
|
||||||
|
|
||||||
requestKey := request.RequestKey()
|
requestKey := request.RequestKey[:]
|
||||||
requestIV := request.RequestIV()
|
requestIV := request.RequestIV[:]
|
||||||
responseKey := md5.Sum(requestKey)
|
responseKey := md5.Sum(requestKey)
|
||||||
responseIV := md5.Sum(requestIV)
|
responseIV := md5.Sum(requestIV)
|
||||||
|
|
||||||
|
5
vid.go
5
vid.go
@ -3,7 +3,8 @@ package core
|
|||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
|
||||||
|
"github.com/v2ray/v2ray-core/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The ID of en entity, in the form of an UUID.
|
// The ID of en entity, in the form of an UUID.
|
||||||
@ -23,7 +24,7 @@ var byteGroups = []int{8, 4, 4, 4, 12}
|
|||||||
func UUIDToVID(uuid string) (v VID, err error) {
|
func UUIDToVID(uuid string) (v VID, err error) {
|
||||||
text := []byte(uuid)
|
text := []byte(uuid)
|
||||||
if len(text) < 32 {
|
if len(text) < 32 {
|
||||||
err = fmt.Errorf("uuid: invalid UUID string: %s", text)
|
err = log.Error("uuid: invalid UUID string: %s", text)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
// VPoint is an single server in V2Ray system.
|
// VPoint is an single server in V2Ray system.
|
||||||
type VPoint struct {
|
type VPoint struct {
|
||||||
Config VConfig
|
Config VConfig
|
||||||
UserSet *VUserSet
|
|
||||||
ichFactory InboundConnectionHandlerFactory
|
ichFactory InboundConnectionHandlerFactory
|
||||||
ochFactory OutboundConnectionHandlerFactory
|
ochFactory OutboundConnectionHandlerFactory
|
||||||
}
|
}
|
||||||
@ -19,12 +18,6 @@ type VPoint struct {
|
|||||||
func NewVPoint(config *VConfig, ichFactory InboundConnectionHandlerFactory, ochFactory OutboundConnectionHandlerFactory) (*VPoint, error) {
|
func NewVPoint(config *VConfig, ichFactory InboundConnectionHandlerFactory, ochFactory OutboundConnectionHandlerFactory) (*VPoint, error) {
|
||||||
var vpoint = new(VPoint)
|
var vpoint = new(VPoint)
|
||||||
vpoint.Config = *config
|
vpoint.Config = *config
|
||||||
vpoint.UserSet = NewVUserSet()
|
|
||||||
|
|
||||||
for _, user := range vpoint.Config.AllowedClients {
|
|
||||||
vpoint.UserSet.AddUser(user)
|
|
||||||
}
|
|
||||||
|
|
||||||
vpoint.ichFactory = ichFactory
|
vpoint.ichFactory = ichFactory
|
||||||
vpoint.ochFactory = ochFactory
|
vpoint.ochFactory = ochFactory
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user