use uuid in vmess id

pull/62/head
v2ray 2015-12-12 21:40:16 +01:00
parent ce32d54a5f
commit a63670311e
9 changed files with 36 additions and 77 deletions

View File

@ -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
}

View File

@ -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)
}

View File

@ -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

View File

@ -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")
} }

View File

@ -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
} }

View File

@ -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()

View File

@ -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)

View File

@ -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{

View File

@ -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()