diff --git a/common/protocol/headers.go b/common/protocol/headers.go index 1304a7e4d..092de5eaa 100644 --- a/common/protocol/headers.go +++ b/common/protocol/headers.go @@ -79,7 +79,7 @@ type ResponseHeader struct { type CommandSwitchAccount struct { Host net.Address Port net.Port - ID *uuid.UUID + ID uuid.UUID Level uint32 AlterIds uint16 ValidMin byte diff --git a/common/protocol/id.go b/common/protocol/id.go index 4360a563d..e6b0176ee 100644 --- a/common/protocol/id.go +++ b/common/protocol/id.go @@ -21,13 +21,13 @@ func DefaultIDHash(key []byte) hash.Hash { // The ID of en entity, in the form of an UUID. type ID struct { - uuid *uuid.UUID + uuid uuid.UUID cmdKey [IDBytesLen]byte } // Equals returns true if this ID equals to the other one. func (id *ID) Equals(another *ID) bool { - return id.uuid.Equals(another.uuid) + return id.uuid.Equals(&(another.uuid)) } func (id *ID) Bytes() []byte { @@ -38,7 +38,7 @@ func (id *ID) String() string { return id.uuid.String() } -func (id *ID) UUID() *uuid.UUID { +func (id *ID) UUID() uuid.UUID { return id.uuid } @@ -47,7 +47,7 @@ func (id ID) CmdKey() []byte { } // NewID returns an ID with given UUID. -func NewID(uuid *uuid.UUID) *ID { +func NewID(uuid uuid.UUID) *ID { id := &ID{uuid: uuid} md5hash := md5.New() common.Must2(md5hash.Write(uuid.Bytes())) diff --git a/common/uuid/uuid.go b/common/uuid/uuid.go index 08225b5d8..0e0ca3869 100644 --- a/common/uuid/uuid.go +++ b/common/uuid/uuid.go @@ -6,6 +6,7 @@ import ( "crypto/rand" "encoding/hex" + "v2ray.com/core/common" "v2ray.com/core/common/errors" ) @@ -46,11 +47,11 @@ func (u *UUID) Equals(another *UUID) bool { } // Next generates a deterministic random UUID based on this UUID. -func (u *UUID) Next() *UUID { +func (u *UUID) Next() UUID { md5hash := md5.New() md5hash.Write(u.Bytes()) md5hash.Write([]byte("16167dc8-16b6-4e6d-b8bb-65dd68113a81")) - newid := new(UUID) + var newid UUID for { md5hash.Sum(newid[:0]) if !newid.Equals(u) { @@ -61,30 +62,31 @@ func (u *UUID) Next() *UUID { } // New creates an UUID with random value. -func New() *UUID { - uuid := new(UUID) - rand.Read(uuid.Bytes()) +func New() UUID { + var uuid UUID + common.Must2(rand.Read(uuid.Bytes())) return uuid } // ParseBytes converts an UUID in byte form to object. -func ParseBytes(b []byte) (*UUID, error) { +func ParseBytes(b []byte) (UUID, error) { + var uuid UUID if len(b) != 16 { - return nil, errors.New("invalid UUID: ", b) + return uuid, errors.New("invalid UUID: ", b) } - uuid := new(UUID) copy(uuid[:], b) return uuid, nil } // ParseString converts an UUID in string form to object. -func ParseString(str string) (*UUID, error) { +func ParseString(str string) (UUID, error) { + var uuid UUID + text := []byte(str) if len(text) < 32 { - return nil, errors.New("invalid UUID: ", str) + return uuid, errors.New("invalid UUID: ", str) } - uuid := new(UUID) b := uuid.Bytes() for _, byteGroup := range byteGroups { @@ -95,7 +97,7 @@ func ParseString(str string) (*UUID, error) { _, err := hex.Decode(b[:byteGroup/2], text[:byteGroup]) if err != nil { - return nil, err + return uuid, err } text = text[byteGroup:] diff --git a/common/uuid/uuid_test.go b/common/uuid/uuid_test.go index f8b90085e..2e7bad4f0 100644 --- a/common/uuid/uuid_test.go +++ b/common/uuid/uuid_test.go @@ -65,7 +65,9 @@ func TestEquals(t *testing.T) { var uuid *UUID = nil var uuid2 *UUID = nil assert(uuid.Equals(uuid2), IsTrue) - assert(uuid.Equals(New()), IsFalse) + + uuid3 := New() + assert(uuid.Equals(&uuid3), IsFalse) } func TestNext(t *testing.T) { @@ -73,5 +75,5 @@ func TestNext(t *testing.T) { uuid := New() uuid2 := uuid.Next() - assert(uuid.Equals(uuid2), IsFalse) + assert(uuid.Equals(&uuid2), IsFalse) } diff --git a/proxy/vmess/encoding/encoding_test.go b/proxy/vmess/encoding/encoding_test.go index 6ed0edc1f..8d0211e48 100644 --- a/proxy/vmess/encoding/encoding_test.go +++ b/proxy/vmess/encoding/encoding_test.go @@ -22,8 +22,9 @@ func TestRequestSerialization(t *testing.T) { Level: 0, Email: "test@v2ray.com", } + id := uuid.New() account := &vmess.Account{ - Id: uuid.New().String(), + Id: id.String(), AlterId: 0, } user.Account = serial.ToTypedMessage(account) diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index df30ae4f9..5553f14e7 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -53,8 +53,9 @@ func (v *userByEmail) Get(email string) (*protocol.User, bool) { v.Lock() user, found = v.cache[email] if !found { + id := uuid.New() account := &vmess.Account{ - Id: uuid.New().String(), + Id: id.String(), AlterId: uint32(v.defaultAlterIDs), } user = &protocol.User{ diff --git a/v2ray.go b/v2ray.go index 7e95eb413..15275f8c8 100644 --- a/v2ray.go +++ b/v2ray.go @@ -37,7 +37,7 @@ type Instance struct { // To make sure V2Ray instance works properly, the config must contain one Dispatcher, one InboundHandlerManager and one OutboundHandlerManager. Other features are optional. func New(config *Config) (*Instance, error) { var server = &Instance{ - id: *(uuid.New()), + id: uuid.New(), } if err := config.Transport.Apply(); err != nil { diff --git a/v2ray_test.go b/v2ray_test.go index 51f120c23..7f287a50a 100644 --- a/v2ray_test.go +++ b/v2ray_test.go @@ -21,6 +21,7 @@ func TestV2RayClose(t *testing.T) { assert := With(t) port := net.Port(dice.RollUint16()) + userId := uuid.New() config := &Config{ App: []*serial.TypedMessage{ serial.ToTypedMessage(&proxyman.InboundConfig{}), @@ -51,7 +52,7 @@ func TestV2RayClose(t *testing.T) { User: []*protocol.User{ { Account: serial.ToTypedMessage(&vmess.Account{ - Id: uuid.New().String(), + Id: userId.String(), }), }, },