mirror of https://github.com/v2ray/v2ray-core
use uuid in vmess id
parent
ce32d54a5f
commit
a63670311e
|
@ -2,10 +2,9 @@ package vmess
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/v2ray/v2ray-core/common/log"
|
"github.com/v2ray/v2ray-core/common/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -18,61 +17,30 @@ var (
|
||||||
|
|
||||||
// The ID of en entity, in the form of an UUID.
|
// The ID of en entity, in the form of an UUID.
|
||||||
type ID struct {
|
type ID struct {
|
||||||
String string
|
uuid *uuid.UUID
|
||||||
Bytes [IDBytesLen]byte
|
|
||||||
cmdKey [IDBytesLen]byte
|
cmdKey [IDBytesLen]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewID(id string) (*ID, error) {
|
func (this *ID) Bytes() []byte {
|
||||||
idBytes, err := UUIDToID(id)
|
return this.uuid.Bytes()
|
||||||
if err != nil {
|
|
||||||
log.Error("Failed to parse id %s", id)
|
|
||||||
return &ID{}, InvalidID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *ID) String() string {
|
||||||
|
return this.uuid.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewID(uuid *uuid.UUID) *ID {
|
||||||
md5hash := md5.New()
|
md5hash := md5.New()
|
||||||
md5hash.Write(idBytes[:])
|
md5hash.Write(uuid.Bytes())
|
||||||
md5hash.Write([]byte("c48619fe-8f02-49e0-b9e9-edf763e17e21"))
|
md5hash.Write([]byte("c48619fe-8f02-49e0-b9e9-edf763e17e21"))
|
||||||
cmdKey := md5.Sum(nil)
|
cmdKey := md5.Sum(nil)
|
||||||
|
|
||||||
return &ID{
|
return &ID{
|
||||||
String: id,
|
uuid: uuid,
|
||||||
Bytes: idBytes,
|
|
||||||
cmdKey: cmdKey,
|
cmdKey: cmdKey,
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v ID) CmdKey() []byte {
|
func (v ID) CmdKey() []byte {
|
||||||
return v.cmdKey[:]
|
return v.cmdKey[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
var byteGroups = []int{8, 4, 4, 4, 12}
|
|
||||||
|
|
||||||
// TODO: leverage a full functional UUID library
|
|
||||||
func UUIDToID(uuid string) (v [IDBytesLen]byte, err error) {
|
|
||||||
text := []byte(uuid)
|
|
||||||
if len(text) < 32 {
|
|
||||||
log.Error("uuid: invalid UUID string: %s", text)
|
|
||||||
err = InvalidID
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
b := v[:]
|
|
||||||
|
|
||||||
for _, byteGroup := range byteGroups {
|
|
||||||
if text[0] == '-' {
|
|
||||||
text = text[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = hex.Decode(b[:byteGroup/2], text[:byteGroup])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
text = text[byteGroup:]
|
|
||||||
b = b[byteGroup/2:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
package vmess
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
v2testing "github.com/v2ray/v2ray-core/testing"
|
|
||||||
"github.com/v2ray/v2ray-core/testing/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestUUIDToID(t *testing.T) {
|
|
||||||
v2testing.Current(t)
|
|
||||||
|
|
||||||
uuid := "2418d087-648d-4990-86e8-19dca1d006d3"
|
|
||||||
expectedBytes := []byte{0x24, 0x18, 0xd0, 0x87, 0x64, 0x8d, 0x49, 0x90, 0x86, 0xe8, 0x19, 0xdc, 0xa1, 0xd0, 0x06, 0xd3}
|
|
||||||
|
|
||||||
actualBytes, _ := NewID(uuid)
|
|
||||||
assert.Bytes(actualBytes.Bytes[:]).Named("UUID").Equals(expectedBytes)
|
|
||||||
}
|
|
|
@ -3,6 +3,7 @@ package json
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/v2ray/v2ray-core/common/uuid"
|
||||||
"github.com/v2ray/v2ray-core/proxy/vmess"
|
"github.com/v2ray/v2ray-core/proxy/vmess"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,11 +24,11 @@ func (u *ConfigUser) UnmarshalJSON(data []byte) error {
|
||||||
if err := json.Unmarshal(data, &rawUserValue); err != nil {
|
if err := json.Unmarshal(data, &rawUserValue); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
id, err := vmess.NewID(rawUserValue.IdString)
|
id, err := uuid.ParseString(rawUserValue.IdString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
u.Id = id
|
u.Id = vmess.NewID(id)
|
||||||
u.Email = rawUserValue.EmailString
|
u.Email = rawUserValue.EmailString
|
||||||
u.LevelValue = vmess.UserLevel(rawUserValue.LevelInt)
|
u.LevelValue = vmess.UserLevel(rawUserValue.LevelInt)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -29,5 +29,5 @@ func TestConfigTargetParsing(t *testing.T) {
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
assert.String(target.Address).Equals("127.0.0.1:80")
|
assert.String(target.Address).Equals("127.0.0.1:80")
|
||||||
assert.Int(len(target.Users)).Equals(1)
|
assert.Int(len(target.Users)).Equals(1)
|
||||||
assert.StringLiteral(target.Users[0].ID().String).Equals("e641f5ad-9397-41e3-bf1a-e8740dfed019")
|
assert.String(target.Users[0].ID()).Equals("e641f5ad-9397-41e3-bf1a-e8740dfed019")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package mocks
|
package mocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/v2ray/v2ray-core/common/uuid"
|
||||||
"github.com/v2ray/v2ray-core/proxy/vmess"
|
"github.com/v2ray/v2ray-core/proxy/vmess"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,6 +25,6 @@ func (us *StaticUserSet) AddUser(user vmess.User) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (us *StaticUserSet) GetUser(userhash []byte) (vmess.User, int64, bool) {
|
func (us *StaticUserSet) GetUser(userhash []byte) (vmess.User, int64, bool) {
|
||||||
id, _ := vmess.NewID("703e9102-eb57-499c-8b59-faf4f371bb21")
|
id, _ := uuid.ParseString("703e9102-eb57-499c-8b59-faf4f371bb21")
|
||||||
return &StaticUser{id: id}, 0, true
|
return &StaticUser{id: vmess.NewID(id)}, 0, true
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ func (us *TimedUserSet) removeEntries(entries <-chan interface{}) {
|
||||||
func (us *TimedUserSet) generateNewHashes(lastSec, nowSec int64, idx int, id *vmess.ID) {
|
func (us *TimedUserSet) generateNewHashes(lastSec, nowSec int64, idx int, id *vmess.ID) {
|
||||||
idHash := NewTimeHash(HMACHash{})
|
idHash := NewTimeHash(HMACHash{})
|
||||||
for lastSec < nowSec {
|
for lastSec < nowSec {
|
||||||
idHash := idHash.Hash(id.Bytes[:], lastSec)
|
idHash := idHash.Hash(id.Bytes(), lastSec)
|
||||||
us.access.Lock()
|
us.access.Lock()
|
||||||
us.userHash[string(idHash)] = indexTimePair{idx, lastSec}
|
us.userHash[string(idHash)] = indexTimePair{idx, lastSec}
|
||||||
us.access.Unlock()
|
us.access.Unlock()
|
||||||
|
|
|
@ -161,7 +161,7 @@ func (this *VMessRequest) ToBytes(idHash user.CounterHash, randomRangeInt64 user
|
||||||
}
|
}
|
||||||
|
|
||||||
counter := randomRangeInt64(time.Now().Unix(), 30)
|
counter := randomRangeInt64(time.Now().Unix(), 30)
|
||||||
hash := idHash.Hash(this.User.ID().Bytes[:], counter)
|
hash := idHash.Hash(this.User.ID().Bytes(), counter)
|
||||||
|
|
||||||
buffer.Append(hash)
|
buffer.Append(hash)
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
|
"github.com/v2ray/v2ray-core/common/uuid"
|
||||||
"github.com/v2ray/v2ray-core/proxy/vmess"
|
"github.com/v2ray/v2ray-core/proxy/vmess"
|
||||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
|
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user"
|
||||||
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user/testing/mocks"
|
"github.com/v2ray/v2ray-core/proxy/vmess/protocol/user/testing/mocks"
|
||||||
|
@ -30,10 +31,10 @@ func (this *TestUser) Level() vmess.UserLevel {
|
||||||
func TestVMessSerialization(t *testing.T) {
|
func TestVMessSerialization(t *testing.T) {
|
||||||
v2testing.Current(t)
|
v2testing.Current(t)
|
||||||
|
|
||||||
userId, err := vmess.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
id, err := uuid.ParseString("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
||||||
if err != nil {
|
assert.Error(err).IsNil()
|
||||||
t.Fatal(err)
|
|
||||||
}
|
userId := vmess.NewID(id)
|
||||||
|
|
||||||
testUser := &TestUser{
|
testUser := &TestUser{
|
||||||
id: userId,
|
id: userId,
|
||||||
|
@ -73,7 +74,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.StringLiteral(actualRequest.User.ID().String).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[:])
|
||||||
|
@ -90,7 +91,10 @@ func TestReadSingleByte(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkVMessRequestWriting(b *testing.B) {
|
func BenchmarkVMessRequestWriting(b *testing.B) {
|
||||||
userId, _ := vmess.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
id, err := uuid.ParseString("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
|
||||||
|
assert.Error(err).IsNil()
|
||||||
|
|
||||||
|
userId := vmess.NewID(id)
|
||||||
userSet := mocks.MockUserSet{[]vmess.User{}, make(map[string]int), make(map[string]int64)}
|
userSet := mocks.MockUserSet{[]vmess.User{}, make(map[string]int), make(map[string]int64)}
|
||||||
|
|
||||||
testUser := &TestUser{
|
testUser := &TestUser{
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||||
v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
|
v2nettesting "github.com/v2ray/v2ray-core/common/net/testing"
|
||||||
|
"github.com/v2ray/v2ray-core/common/uuid"
|
||||||
"github.com/v2ray/v2ray-core/proxy/common/connhandler"
|
"github.com/v2ray/v2ray-core/proxy/common/connhandler"
|
||||||
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"
|
||||||
|
@ -23,9 +24,11 @@ import (
|
||||||
func TestVMessInAndOut(t *testing.T) {
|
func TestVMessInAndOut(t *testing.T) {
|
||||||
v2testing.Current(t)
|
v2testing.Current(t)
|
||||||
|
|
||||||
testAccount, err := vmess.NewID("ad937d9d-6e23-4a5a-ba23-bce5092a7c51")
|
id, err := uuid.ParseString("ad937d9d-6e23-4a5a-ba23-bce5092a7c51")
|
||||||
assert.Error(err).IsNil()
|
assert.Error(err).IsNil()
|
||||||
|
|
||||||
|
testAccount := vmess.NewID(id)
|
||||||
|
|
||||||
portA := v2nettesting.PickPort()
|
portA := v2nettesting.PickPort()
|
||||||
portB := v2nettesting.PickPort()
|
portB := v2nettesting.PickPort()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue