mirror of https://github.com/v2ray/v2ray-core
				
				
				
			re-enable vmess test
							parent
							
								
									8f93612dec
								
							
						
					
					
						commit
						228e1eeabe
					
				| 
						 | 
					@ -0,0 +1,51 @@
 | 
				
			||||||
 | 
					package hash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/hmac"
 | 
				
			||||||
 | 
						"crypto/md5"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CounterHash interface {
 | 
				
			||||||
 | 
						Hash(key []byte, counter int64) []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type StringHash interface {
 | 
				
			||||||
 | 
						Hash(key []byte, data []byte) []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TimeHash struct {
 | 
				
			||||||
 | 
						baseHash StringHash
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewTimeHash(baseHash StringHash) CounterHash {
 | 
				
			||||||
 | 
						return TimeHash{
 | 
				
			||||||
 | 
							baseHash: baseHash,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h TimeHash) Hash(key []byte, counter int64) []byte {
 | 
				
			||||||
 | 
						counterBytes := int64ToBytes(counter)
 | 
				
			||||||
 | 
						return h.baseHash.Hash(key, counterBytes)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type HMACHash struct {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h HMACHash) Hash(key []byte, data []byte) []byte {
 | 
				
			||||||
 | 
						hash := hmac.New(md5.New, key)
 | 
				
			||||||
 | 
						hash.Write(data)
 | 
				
			||||||
 | 
						return hash.Sum(nil)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func int64ToBytes(value int64) []byte {
 | 
				
			||||||
 | 
						return []byte{
 | 
				
			||||||
 | 
							byte(value >> 56),
 | 
				
			||||||
 | 
							byte(value >> 48),
 | 
				
			||||||
 | 
							byte(value >> 40),
 | 
				
			||||||
 | 
							byte(value >> 32),
 | 
				
			||||||
 | 
							byte(value >> 24),
 | 
				
			||||||
 | 
							byte(value >> 16),
 | 
				
			||||||
 | 
							byte(value >> 8),
 | 
				
			||||||
 | 
							byte(value),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					package hash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/md5"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Int64Hash(value int64) []byte {
 | 
				
			||||||
 | 
						md5hash := md5.New()
 | 
				
			||||||
 | 
						buffer := int64ToBytes(value)
 | 
				
			||||||
 | 
						md5hash.Write(buffer)
 | 
				
			||||||
 | 
						md5hash.Write(buffer)
 | 
				
			||||||
 | 
						md5hash.Write(buffer)
 | 
				
			||||||
 | 
						md5hash.Write(buffer)
 | 
				
			||||||
 | 
						return md5hash.Sum(nil)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										56
									
								
								id.go
								
								
								
								
							
							
						
						
									
										56
									
								
								id.go
								
								
								
								
							| 
						 | 
					@ -1,11 +1,8 @@
 | 
				
			||||||
package core
 | 
					package core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"crypto/hmac"
 | 
					 | 
				
			||||||
	"crypto/md5"
 | 
						"crypto/md5"
 | 
				
			||||||
	"encoding/hex"
 | 
						"encoding/hex"
 | 
				
			||||||
	mrand "math/rand"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/v2ray/v2ray-core/log"
 | 
						"github.com/v2ray/v2ray-core/log"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -32,60 +29,17 @@ func NewID(id string) (ID, error) {
 | 
				
			||||||
	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{id, idBytes, cmdKey[:]}, nil
 | 
						return ID{
 | 
				
			||||||
}
 | 
							String: id,
 | 
				
			||||||
 | 
							Bytes:  idBytes,
 | 
				
			||||||
func (v ID) TimeRangeHash(rangeSec int) ([]byte, int64) {
 | 
							cmdKey: cmdKey[:],
 | 
				
			||||||
	nowSec := time.Now().UTC().Unix()
 | 
						}, nil
 | 
				
			||||||
	delta := mrand.Intn(rangeSec*2) - rangeSec
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	targetSec := nowSec + int64(delta)
 | 
					 | 
				
			||||||
	return v.TimeHash(targetSec), targetSec
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v ID) TimeHash(timeSec int64) []byte {
 | 
					 | 
				
			||||||
	buffer := []byte{
 | 
					 | 
				
			||||||
		byte(timeSec >> 56),
 | 
					 | 
				
			||||||
		byte(timeSec >> 48),
 | 
					 | 
				
			||||||
		byte(timeSec >> 40),
 | 
					 | 
				
			||||||
		byte(timeSec >> 32),
 | 
					 | 
				
			||||||
		byte(timeSec >> 24),
 | 
					 | 
				
			||||||
		byte(timeSec >> 16),
 | 
					 | 
				
			||||||
		byte(timeSec >> 8),
 | 
					 | 
				
			||||||
		byte(timeSec),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return v.Hash(buffer)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (v ID) Hash(data []byte) []byte {
 | 
					 | 
				
			||||||
	hasher := hmac.New(md5.New, v.Bytes)
 | 
					 | 
				
			||||||
	hasher.Write(data)
 | 
					 | 
				
			||||||
	return hasher.Sum(nil)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (v ID) CmdKey() []byte {
 | 
					func (v ID) CmdKey() []byte {
 | 
				
			||||||
	return v.cmdKey
 | 
						return v.cmdKey
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TimestampHash(timeSec int64) []byte {
 | 
					 | 
				
			||||||
	md5hash := md5.New()
 | 
					 | 
				
			||||||
	buffer := []byte{
 | 
					 | 
				
			||||||
		byte(timeSec >> 56),
 | 
					 | 
				
			||||||
		byte(timeSec >> 48),
 | 
					 | 
				
			||||||
		byte(timeSec >> 40),
 | 
					 | 
				
			||||||
		byte(timeSec >> 32),
 | 
					 | 
				
			||||||
		byte(timeSec >> 24),
 | 
					 | 
				
			||||||
		byte(timeSec >> 16),
 | 
					 | 
				
			||||||
		byte(timeSec >> 8),
 | 
					 | 
				
			||||||
		byte(timeSec),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	md5hash.Write(buffer)
 | 
					 | 
				
			||||||
	md5hash.Write(buffer)
 | 
					 | 
				
			||||||
	md5hash.Write(buffer)
 | 
					 | 
				
			||||||
	md5hash.Write(buffer)
 | 
					 | 
				
			||||||
	return md5hash.Sum(nil)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var byteGroups = []int{8, 4, 4, 4, 12}
 | 
					var byteGroups = []int{8, 4, 4, 4, 12}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: leverage a full functional UUID library
 | 
					// TODO: leverage a full functional UUID library
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,7 @@ func TestAuthenticationResponseWrite(t *testing.T) {
 | 
				
			||||||
	response := NewAuthenticationResponse(byte(0x05))
 | 
						response := NewAuthenticationResponse(byte(0x05))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buffer := bytes.NewBuffer(make([]byte, 0, 10))
 | 
						buffer := bytes.NewBuffer(make([]byte, 0, 10))
 | 
				
			||||||
	WriteAuthentication(buffer, &response)
 | 
						WriteAuthentication(buffer, response)
 | 
				
			||||||
	assert.Bytes(buffer.Bytes()).Equals([]byte{socksVersion, byte(0x05)})
 | 
						assert.Bytes(buffer.Bytes()).Equals([]byte{socksVersion, byte(0x05)})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					package socks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						v2net "github.com/v2ray/v2ray-core/net"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Socks5UDPRequest struct {
 | 
				
			||||||
 | 
						fragment byte
 | 
				
			||||||
 | 
						address  v2net.Address
 | 
				
			||||||
 | 
						data     []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ReadUDPRequest(reader io.Reader) (request Socks5UDPRequest, err error) {
 | 
				
			||||||
 | 
						//buf := make([]byte, 4 * 1024) // Regular UDP packet size is 1500 bytes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -10,10 +10,13 @@ import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	mrand "math/rand"
 | 
						mrand "math/rand"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/v2ray/v2ray-core"
 | 
						"github.com/v2ray/v2ray-core"
 | 
				
			||||||
 | 
						v2hash "github.com/v2ray/v2ray-core/hash"
 | 
				
			||||||
	v2io "github.com/v2ray/v2ray-core/io"
 | 
						v2io "github.com/v2ray/v2ray-core/io"
 | 
				
			||||||
	"github.com/v2ray/v2ray-core/log"
 | 
						"github.com/v2ray/v2ray-core/log"
 | 
				
			||||||
 | 
						v2math "github.com/v2ray/v2ray-core/math"
 | 
				
			||||||
	v2net "github.com/v2ray/v2ray-core/net"
 | 
						v2net "github.com/v2ray/v2ray-core/net"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,7 +60,6 @@ func NewVMessRequestReader(vUserSet core.UserSet) *VMessRequestReader {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
 | 
					func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
	buffer := make([]byte, 256)
 | 
						buffer := make([]byte, 256)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nBytes, err := reader.Read(buffer[:core.IDBytesLen])
 | 
						nBytes, err := reader.Read(buffer[:core.IDBytesLen])
 | 
				
			||||||
| 
						 | 
					@ -76,7 +78,7 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	aesStream := cipher.NewCFBDecrypter(aesCipher, core.TimestampHash(timeSec))
 | 
						aesStream := cipher.NewCFBDecrypter(aesCipher, v2hash.Int64Hash(timeSec))
 | 
				
			||||||
	decryptor := v2io.NewCryptionReader(aesStream, reader)
 | 
						decryptor := v2io.NewCryptionReader(aesStream, reader)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -180,18 +182,25 @@ func (r *VMessRequestReader) Read(reader io.Reader) (*VMessRequest, error) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type VMessRequestWriter struct {
 | 
					type VMessRequestWriter struct {
 | 
				
			||||||
 | 
						idHash           v2hash.CounterHash
 | 
				
			||||||
 | 
						randomRangeInt64 v2math.RandomInt64InRange
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewVMessRequestWriter() *VMessRequestWriter {
 | 
					func NewVMessRequestWriter(idHash v2hash.CounterHash, randomRangeInt64 v2math.RandomInt64InRange) *VMessRequestWriter {
 | 
				
			||||||
	return &VMessRequestWriter{}
 | 
						return &VMessRequestWriter{
 | 
				
			||||||
 | 
							idHash:           idHash,
 | 
				
			||||||
 | 
							randomRangeInt64: randomRangeInt64,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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)
 | 
				
			||||||
	userHash, timeSec := request.UserId.TimeRangeHash(30)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log.Debug("Writing userhash: %v", userHash)
 | 
						counter := w.randomRangeInt64(time.Now().UTC().Unix(), 30)
 | 
				
			||||||
	buffer = append(buffer, userHash...)
 | 
						idHash := w.idHash.Hash(request.UserId.Bytes, counter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log.Debug("Writing userhash: %v", idHash)
 | 
				
			||||||
 | 
						buffer = append(buffer, idHash...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	encryptionBegin := len(buffer)
 | 
						encryptionBegin := len(buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -241,7 +250,7 @@ func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) erro
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	aesStream := cipher.NewCFBEncrypter(aesCipher, core.TimestampHash(timeSec))
 | 
						aesStream := cipher.NewCFBEncrypter(aesCipher, v2hash.Int64Hash(counter))
 | 
				
			||||||
	cWriter := v2io.NewCryptionWriter(aesStream, writer)
 | 
						cWriter := v2io.NewCryptionWriter(aesStream, writer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err = writer.Write(buffer[0:encryptionBegin])
 | 
						_, err = writer.Write(buffer[0:encryptionBegin])
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,13 +7,14 @@ import (
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/v2ray/v2ray-core"
 | 
						"github.com/v2ray/v2ray-core"
 | 
				
			||||||
 | 
						v2hash "github.com/v2ray/v2ray-core/hash"
 | 
				
			||||||
 | 
						v2math "github.com/v2ray/v2ray-core/math"
 | 
				
			||||||
	v2net "github.com/v2ray/v2ray-core/net"
 | 
						v2net "github.com/v2ray/v2ray-core/net"
 | 
				
			||||||
	"github.com/v2ray/v2ray-core/testing/mocks"
 | 
						"github.com/v2ray/v2ray-core/testing/mocks"
 | 
				
			||||||
	"github.com/v2ray/v2ray-core/testing/unit"
 | 
						"github.com/v2ray/v2ray-core/testing/unit"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestVMessSerialization(t *testing.T) {
 | 
					func TestVMessSerialization(t *testing.T) {
 | 
				
			||||||
	t.Skip()
 | 
					 | 
				
			||||||
	assert := unit.Assert(t)
 | 
						assert := unit.Assert(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	userId, err := core.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
 | 
						userId, err := core.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
 | 
				
			||||||
| 
						 | 
					@ -21,7 +22,7 @@ func TestVMessSerialization(t *testing.T) {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	userSet := mocks.MockUserSet{[]core.ID{}, make(map[string]int)}
 | 
						userSet := mocks.MockUserSet{[]core.ID{}, make(map[string]int), make(map[string]int64)}
 | 
				
			||||||
	userSet.AddUser(core.User{userId})
 | 
						userSet.AddUser(core.User{userId})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	request := new(VMessRequest)
 | 
						request := new(VMessRequest)
 | 
				
			||||||
| 
						 | 
					@ -47,13 +48,15 @@ func TestVMessSerialization(t *testing.T) {
 | 
				
			||||||
	request.Address = v2net.DomainAddress("v2ray.com", 80)
 | 
						request.Address = v2net.DomainAddress("v2ray.com", 80)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buffer := bytes.NewBuffer(make([]byte, 0, 300))
 | 
						buffer := bytes.NewBuffer(make([]byte, 0, 300))
 | 
				
			||||||
	requestWriter := NewVMessRequestWriter()
 | 
						mockTime := int64(1823730)
 | 
				
			||||||
 | 
						requestWriter := NewVMessRequestWriter(v2hash.NewTimeHash(v2hash.HMACHash{}), func(base int64, delta int) int64 { return mockTime })
 | 
				
			||||||
	err = requestWriter.Write(buffer, request)
 | 
						err = requestWriter.Write(buffer, request)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	userSet.UserHashes[string(buffer.Bytes()[:16])] = 0
 | 
						userSet.UserHashes[string(buffer.Bytes()[:16])] = 0
 | 
				
			||||||
 | 
						userSet.Timestamps[string(buffer.Bytes()[:16])] = mockTime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	requestReader := NewVMessRequestReader(&userSet)
 | 
						requestReader := NewVMessRequestReader(&userSet)
 | 
				
			||||||
	actualRequest, err := requestReader.Read(buffer)
 | 
						actualRequest, err := requestReader.Read(buffer)
 | 
				
			||||||
| 
						 | 
					@ -72,7 +75,7 @@ func TestVMessSerialization(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func BenchmarkVMessRequestWriting(b *testing.B) {
 | 
					func BenchmarkVMessRequestWriting(b *testing.B) {
 | 
				
			||||||
	userId, _ := core.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
 | 
						userId, _ := core.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51")
 | 
				
			||||||
	userSet := mocks.MockUserSet{[]core.ID{}, make(map[string]int)}
 | 
						userSet := mocks.MockUserSet{[]core.ID{}, make(map[string]int), make(map[string]int64)}
 | 
				
			||||||
	userSet.AddUser(core.User{userId})
 | 
						userSet.AddUser(core.User{userId})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	request := new(VMessRequest)
 | 
						request := new(VMessRequest)
 | 
				
			||||||
| 
						 | 
					@ -86,7 +89,7 @@ func BenchmarkVMessRequestWriting(b *testing.B) {
 | 
				
			||||||
	request.Command = byte(0x01)
 | 
						request.Command = byte(0x01)
 | 
				
			||||||
	request.Address = v2net.DomainAddress("v2ray.com", 80)
 | 
						request.Address = v2net.DomainAddress("v2ray.com", 80)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	requestWriter := NewVMessRequestWriter()
 | 
						requestWriter := NewVMessRequestWriter(v2hash.NewTimeHash(v2hash.HMACHash{}), v2math.GenerateRandomInt64InRange)
 | 
				
			||||||
	for i := 0; i < b.N; i++ {
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
		requestWriter.Write(ioutil.Discard, request)
 | 
							requestWriter.Write(ioutil.Discard, request)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					package math
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"math/rand"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type RandomInt64InRange func(base int64, delta int) int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GenerateRandomInt64InRange(base int64, delta int) int64 {
 | 
				
			||||||
 | 
						rangeInDelta := rand.Intn(delta*2) - delta
 | 
				
			||||||
 | 
						return base + int64(rangeInDelta)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -7,9 +7,11 @@ import (
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/v2ray/v2ray-core"
 | 
						"github.com/v2ray/v2ray-core"
 | 
				
			||||||
 | 
						v2hash "github.com/v2ray/v2ray-core/hash"
 | 
				
			||||||
	v2io "github.com/v2ray/v2ray-core/io"
 | 
						v2io "github.com/v2ray/v2ray-core/io"
 | 
				
			||||||
	vmessio "github.com/v2ray/v2ray-core/io/vmess"
 | 
						vmessio "github.com/v2ray/v2ray-core/io/vmess"
 | 
				
			||||||
	"github.com/v2ray/v2ray-core/log"
 | 
						"github.com/v2ray/v2ray-core/log"
 | 
				
			||||||
 | 
						v2math "github.com/v2ray/v2ray-core/math"
 | 
				
			||||||
	v2net "github.com/v2ray/v2ray-core/net"
 | 
						v2net "github.com/v2ray/v2ray-core/net"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,7 +96,7 @@ func startCommunicate(request *vmessio.VMessRequest, dest v2net.Address, ray cor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func handleRequest(conn *net.TCPConn, request *vmessio.VMessRequest, input <-chan []byte, finish chan<- bool) error {
 | 
					func handleRequest(conn *net.TCPConn, request *vmessio.VMessRequest, input <-chan []byte, finish chan<- bool) error {
 | 
				
			||||||
	defer close(finish)
 | 
						defer close(finish)
 | 
				
			||||||
	requestWriter := vmessio.NewVMessRequestWriter()
 | 
						requestWriter := vmessio.NewVMessRequestWriter(v2hash.NewTimeHash(v2hash.HMACHash{}), v2math.GenerateRandomInt64InRange)
 | 
				
			||||||
	err := requestWriter.Write(conn, request)
 | 
						err := requestWriter.Write(conn, request)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error("Failed to write VMess request: %v", err)
 | 
							log.Error("Failed to write VMess request: %v", err)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ import (
 | 
				
			||||||
type MockUserSet struct {
 | 
					type MockUserSet struct {
 | 
				
			||||||
	UserIds    []core.ID
 | 
						UserIds    []core.ID
 | 
				
			||||||
	UserHashes map[string]int
 | 
						UserHashes map[string]int
 | 
				
			||||||
 | 
						Timestamps map[string]int64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (us *MockUserSet) AddUser(user core.User) error {
 | 
					func (us *MockUserSet) AddUser(user core.User) error {
 | 
				
			||||||
| 
						 | 
					@ -17,7 +18,7 @@ func (us *MockUserSet) AddUser(user core.User) error {
 | 
				
			||||||
func (us *MockUserSet) GetUser(userhash []byte) (*core.ID, int64, bool) {
 | 
					func (us *MockUserSet) GetUser(userhash []byte) (*core.ID, int64, bool) {
 | 
				
			||||||
	idx, found := us.UserHashes[string(userhash)]
 | 
						idx, found := us.UserHashes[string(userhash)]
 | 
				
			||||||
	if found {
 | 
						if found {
 | 
				
			||||||
		return &us.UserIds[idx], 1234, true
 | 
							return &us.UserIds[idx], us.Timestamps[string(userhash)], true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil, 0, false
 | 
						return nil, 0, false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,8 @@ package core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						v2hash "github.com/v2ray/v2ray-core/hash"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
| 
						 | 
					@ -44,6 +46,7 @@ func (us *TimedUserSet) updateUserHash(tick <-chan time.Time) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hash2Remove := make(chan hashEntry, cacheDurationSec*3*len(us.validUserIds))
 | 
						hash2Remove := make(chan hashEntry, cacheDurationSec*3*len(us.validUserIds))
 | 
				
			||||||
	lastSec2Remove := now.Unix()
 | 
						lastSec2Remove := now.Unix()
 | 
				
			||||||
 | 
						idHash := v2hash.NewTimeHash(v2hash.HMACHash{})
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		now := <-tick
 | 
							now := <-tick
 | 
				
			||||||
		nowSec := now.UTC().Unix()
 | 
							nowSec := now.UTC().Unix()
 | 
				
			||||||
| 
						 | 
					@ -59,7 +62,7 @@ func (us *TimedUserSet) updateUserHash(tick <-chan time.Time) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for lastSec < nowSec+cacheDurationSec {
 | 
							for lastSec < nowSec+cacheDurationSec {
 | 
				
			||||||
			for idx, id := range us.validUserIds {
 | 
								for idx, id := range us.validUserIds {
 | 
				
			||||||
				idHash := id.TimeHash(lastSec)
 | 
									idHash := idHash.Hash(id.Bytes, lastSec)
 | 
				
			||||||
				hash2Remove <- hashEntry{string(idHash), lastSec}
 | 
									hash2Remove <- hashEntry{string(idHash), lastSec}
 | 
				
			||||||
				us.userHashes[string(idHash)] = indexTimePair{idx, lastSec}
 | 
									us.userHashes[string(idHash)] = indexTimePair{idx, lastSec}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue