func handleRequest(conn *net.TCPConn, request *vmessio.VMessRequest, input <-chan []byte, finish chan<- bool) { defer close(finish) encryptRequestWriter, err := v2io.NewAesEncryptWriter(request.RequestKey[:], request.RequestIV[:], conn) if err != nil { log.Error("VMessOut: Failed to create encrypt writer: %v", err) return } buffer, err := request.ToBytes(v2hash.NewTimeHash(v2hash.HMACHash{}), v2math.GenerateRandomInt64InRange) if err != nil { log.Error("VMessOut: Failed to serialize VMess request: %v", err) return } // Send first packet of payload together with request, in favor of small requests. payload, open := <-input if open { encryptRequestWriter.Crypt(payload) buffer = append(buffer, payload...) _, err = conn.Write(buffer) if err != nil { log.Error("VMessOut: Failed to write VMess request: %v", err) return } v2net.ChanToWriter(encryptRequestWriter, input) } return }
func handleRequest(conn *net.TCPConn, request *vmessio.VMessRequest, input <-chan []byte, finish chan<- bool) error { defer close(finish) encryptRequestWriter, err := v2io.NewAesEncryptWriter(request.RequestKey[:], request.RequestIV[:], conn) if err != nil { log.Error("Failed to create encrypt writer: %v", err) return err } buffer, err := request.ToBytes(v2hash.NewTimeHash(v2hash.HMACHash{}), v2math.GenerateRandomInt64InRange) if err != nil { log.Error("VMessOut: Failed to serialize VMess request: %v", err) } //conn.Write(buffer) data, open := <-input if open { encryptRequestWriter.Crypt(data) buffer = append(buffer, data...) } _, err = conn.Write(buffer) if err != nil { log.Error("VMessOut: Failed to write VMess request: %v", err) } if !open { return nil } v2net.ChanToWriter(encryptRequestWriter, input) return nil }
func (us *TimedUserSet) updateUserHash(tick <-chan time.Time) { now := time.Now().UTC() lastSec := now.Unix() - cacheDurationSec hash2Remove := make(chan hashEntry, cacheDurationSec*3*len(us.validUserIds)) lastSec2Remove := now.Unix() idHash := v2hash.NewTimeHash(v2hash.HMACHash{}) for { now := <-tick nowSec := now.UTC().Unix() remove2Sec := nowSec - cacheDurationSec if remove2Sec > lastSec2Remove { for lastSec2Remove+1 < remove2Sec { entry := <-hash2Remove lastSec2Remove = entry.timeSec delete(us.userHashes, entry.hash) } } for lastSec < nowSec+cacheDurationSec { for idx, id := range us.validUserIds { idHash := idHash.Hash(id.Bytes, lastSec) hash2Remove <- hashEntry{string(idHash), lastSec} us.userHashes[string(idHash)] = indexTimePair{idx, lastSec} } lastSec++ } } }
func TestVMessSerialization(t *testing.T) { assert := unit.Assert(t) userId, err := core.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51") if err != nil { t.Fatal(err) } userSet := mocks.MockUserSet{[]core.ID{}, make(map[string]int), make(map[string]int64)} userSet.AddUser(core.User{userId}) request := new(VMessRequest) request.Version = byte(0x01) request.UserId = userId _, err = rand.Read(request.RequestIV[:]) if err != nil { t.Fatal(err) } _, err = rand.Read(request.RequestKey[:]) if err != nil { t.Fatal(err) } _, err = rand.Read(request.ResponseHeader[:]) if err != nil { t.Fatal(err) } request.Command = byte(0x01) request.Address = v2net.DomainAddress("v2ray.com", 80) buffer := bytes.NewBuffer(make([]byte, 0, 300)) mockTime := int64(1823730) requestWriter := NewVMessRequestWriter(v2hash.NewTimeHash(v2hash.HMACHash{}), func(base int64, delta int) int64 { return mockTime }) err = requestWriter.Write(buffer, request) if err != nil { t.Fatal(err) } userSet.UserHashes[string(buffer.Bytes()[:16])] = 0 userSet.Timestamps[string(buffer.Bytes()[:16])] = mockTime requestReader := NewVMessRequestReader(&userSet) actualRequest, err := requestReader.Read(buffer) if err != nil { t.Fatal(err) } assert.Byte(actualRequest.Version).Named("Version").Equals(byte(0x01)) assert.String(actualRequest.UserId.String).Named("UserId").Equals(request.UserId.String) assert.Bytes(actualRequest.RequestIV[:]).Named("RequestIV").Equals(request.RequestIV[:]) assert.Bytes(actualRequest.RequestKey[:]).Named("RequestKey").Equals(request.RequestKey[:]) assert.Bytes(actualRequest.ResponseHeader[:]).Named("ResponseHeader").Equals(request.ResponseHeader[:]) assert.Byte(actualRequest.Command).Named("Command").Equals(request.Command) assert.String(actualRequest.Address.String()).Named("Address").Equals(request.Address.String()) }
func handleRequest(conn *net.TCPConn, request *vmessio.VMessRequest, input <-chan []byte, finish chan<- bool) error { defer close(finish) requestWriter := vmessio.NewVMessRequestWriter(v2hash.NewTimeHash(v2hash.HMACHash{}), v2math.GenerateRandomInt64InRange) err := requestWriter.Write(conn, request) if err != nil { log.Error("Failed to write VMess request: %v", err) return err } encryptRequestWriter, err := v2io.NewAesEncryptWriter(request.RequestKey[:], request.RequestIV[:], conn) if err != nil { log.Error("Failed to create encrypt writer: %v", err) return err } v2net.ChanToWriter(encryptRequestWriter, input) return nil }
func BenchmarkVMessRequestWriting(b *testing.B) { userId, _ := core.NewID("2b2966ac-16aa-4fbf-8d81-c5f172a3da51") userSet := mocks.MockUserSet{[]core.ID{}, make(map[string]int), make(map[string]int64)} userSet.AddUser(core.User{userId}) request := new(VMessRequest) request.Version = byte(0x01) request.UserId = userId rand.Read(request.RequestIV[:]) rand.Read(request.RequestKey[:]) rand.Read(request.ResponseHeader[:]) request.Command = byte(0x01) request.Address = v2net.DomainAddress("v2ray.com", 80) for i := 0; i < b.N; i++ { request.ToBytes(v2hash.NewTimeHash(v2hash.HMACHash{}), v2math.GenerateRandomInt64InRange) } }