1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-10 01:40:44 +00:00

refine buffer usage

This commit is contained in:
Darien Raymond 2016-12-05 15:19:14 +01:00
parent 9ecf89657c
commit cf3eb0e77d
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
16 changed files with 73 additions and 45 deletions

View File

@ -103,7 +103,7 @@ func (v *UDPNameServer) AssignUnusedID(response chan<- *ARecord) uint16 {
// Private: Visible for testing.
func (v *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc.Buffer) {
msg := new(dns.Msg)
err := msg.Unpack(payload.Value)
err := msg.Unpack(payload.Bytes())
if err != nil {
log.Warning("DNS: Failed to parse DNS response: ", err)
return
@ -156,7 +156,7 @@ func (v *UDPNameServer) BuildQueryA(domain string, id uint16) *alloc.Buffer {
Qclass: dns.ClassINET,
}}
writtenBuffer, _ := msg.PackBuffer(buffer.Value)
writtenBuffer, _ := msg.PackBuffer(buffer.Bytes())
buffer.Slice(0, len(writtenBuffer))
return buffer

View File

@ -117,11 +117,39 @@ func (b *Buffer) PrependHash(h hash.Hash) *Buffer {
return b
}
func (b *Buffer) Byte(index int) byte {
return b.Value[index]
}
// Bytes returns the content bytes of this Buffer.
func (b *Buffer) Bytes() []byte {
return b.Value
}
func (b *Buffer) BytesRange(from, to int) []byte {
if from < 0 {
from += len(b.Value)
}
if to < 0 {
to += len(b.Value)
}
return b.Value[from:to]
}
func (b *Buffer) BytesFrom(from int) []byte {
if from < 0 {
from += len(b.Value)
}
return b.Value[from:]
}
func (b *Buffer) BytesTo(to int) []byte {
if to < 0 {
to += len(b.Value)
}
return b.Value[:to]
}
// Slice cuts the buffer at the given position.
func (b *Buffer) Slice(from, to int) *Buffer {
b.offset += from

View File

@ -43,10 +43,10 @@ func TestBufferPrepend(t *testing.T) {
buffer.Prepend([]byte{'x', 'y', 'z'})
assert.Int(buffer.Len()).Equals(6)
assert.Bytes(buffer.Value).Equals([]byte("xyzabc"))
assert.String(buffer.String()).Equals("xyzabc")
buffer.Prepend([]byte{'u', 'v', 'w'})
assert.Bytes(buffer.Value).Equals([]byte("uvwxyzabc"))
assert.String(buffer.String()).Equals("uvwxyzabc")
}
func TestBufferString(t *testing.T) {

View File

@ -87,7 +87,7 @@ func (v *BufferedWriter) Flush() error {
func (v *BufferedWriter) FlushWithoutLock() error {
defer v.buffer.Clear()
for !v.buffer.IsEmpty() {
nBytes, err := v.writer.Write(v.buffer.Value)
nBytes, err := v.writer.Write(v.buffer.Bytes())
if err != nil {
return err
}

View File

@ -49,5 +49,5 @@ func TestBufferedWriterLargePayload(t *testing.T) {
nBytes, err = writer.Write(payload[1024:])
assert.Error(err).IsNil()
assert.Int(nBytes).Equals(63 * 1024)
assert.Bytes(content.Value).Equals(payload)
assert.Bytes(content.Bytes()).Equals(payload)
}

View File

@ -30,7 +30,7 @@ func NewAdaptiveWriter(writer io.Writer) *AdaptiveWriter {
func (v *AdaptiveWriter) Write(buffer *alloc.Buffer) error {
defer buffer.Release()
for !buffer.IsEmpty() {
nBytes, err := v.writer.Write(buffer.Value)
nBytes, err := v.writer.Write(buffer.Bytes())
if err != nil {
return err
}

View File

@ -13,8 +13,8 @@ import (
func TestAdaptiveWriter(t *testing.T) {
assert := assert.On(t)
lb := alloc.NewBuffer()
rand.Read(lb.Value)
lb := alloc.NewBuffer().Clear()
lb.FillFrom(rand.Reader)
writeBuffer := make([]byte, 0, 1024*1024)

View File

@ -126,7 +126,7 @@ func (v *DokodemoDoor) handleUDPResponse(dest v2net.Destination, payload *alloc.
if !v.accepting {
return
}
v.udpHub.WriteTo(payload.Value, dest)
v.udpHub.WriteTo(payload.Bytes(), dest)
}
func (v *DokodemoDoor) ListenTCP() error {

View File

@ -96,7 +96,7 @@ func (v *FreedomConnection) Dispatch(destination v2net.Destination, payload *all
output := ray.OutboundOutput()
if !payload.IsEmpty() {
conn.Write(payload.Value)
conn.Write(payload.Bytes())
}
go func() {

View File

@ -54,7 +54,7 @@ func TestSinglePacket(t *testing.T) {
respPayload, err := traffic.InboundOutput().Read()
assert.Error(err).IsNil()
assert.Bytes(respPayload.Value).Equals([]byte("Processed: Data to be sent to remote"))
assert.String(respPayload.String()).Equals("Processed: Data to be sent to remote")
tcpServer.Close()
}

View File

@ -72,26 +72,26 @@ func (v *ChunkReader) Release() {
func (v *ChunkReader) Read() (*alloc.Buffer, error) {
buffer := alloc.NewBuffer()
if _, err := io.ReadFull(v.reader, buffer.Value[:2]); err != nil {
if _, err := io.ReadFull(v.reader, buffer.BytesTo(2)); err != nil {
buffer.Release()
return nil, err
}
// There is a potential buffer overflow here. Large buffer is 64K bytes,
// while uin16 + 10 will be more than that
length := serial.BytesToUint16(buffer.Value[:2]) + AuthSize
length := serial.BytesToUint16(buffer.BytesTo(2)) + AuthSize
if length > alloc.BufferSize {
// Theoretically the size of a chunk is 64K, but most Shadowsocks implementations used <4K buffer.
buffer.Release()
buffer = alloc.NewLocalBuffer(int(length) + 128)
}
if _, err := io.ReadFull(v.reader, buffer.Value[:length]); err != nil {
if _, err := io.ReadFull(v.reader, buffer.BytesTo(int(length))); err != nil {
buffer.Release()
return nil, err
}
buffer.Slice(0, int(length))
authBytes := buffer.Value[:AuthSize]
payload := buffer.Value[AuthSize:]
authBytes := buffer.BytesTo(AuthSize)
payload := buffer.BytesFrom(AuthSize)
actualAuthBytes := v.auth.Authenticate(nil, payload)
if !bytes.Equal(authBytes, actualAuthBytes) {
@ -123,7 +123,7 @@ func (v *ChunkWriter) Release() {
func (v *ChunkWriter) Write(payload *alloc.Buffer) error {
totalLength := payload.Len()
payload.SliceBack(AuthSize)
v.auth.Authenticate(payload.Value[:0], payload.Value[AuthSize:])
v.auth.Authenticate(payload.BytesTo(0), payload.BytesFrom(AuthSize))
payload.PrependUint16(uint16(totalLength))
_, err := v.writer.Write(payload.Bytes())
return err

View File

@ -17,10 +17,10 @@ func TestNormalChunkReading(t *testing.T) {
[]byte{21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36})))
payload, err := reader.Read()
assert.Error(err).IsNil()
assert.Bytes(payload.Value).Equals([]byte{11, 12, 13, 14, 15, 16, 17, 18})
assert.Bytes(payload.Bytes()).Equals([]byte{11, 12, 13, 14, 15, 16, 17, 18})
payload.PrependBytes(3, 4)
assert.Bytes(payload.Value).Equals([]byte{3, 4, 11, 12, 13, 14, 15, 16, 17, 18})
assert.Bytes(payload.Bytes()).Equals([]byte{3, 4, 11, 12, 13, 14, 15, 16, 17, 18})
}
func TestNormalChunkWriting(t *testing.T) {
@ -32,5 +32,5 @@ func TestNormalChunkWriting(t *testing.T) {
err := writer.Write(alloc.NewLocalBuffer(256).Clear().Append([]byte{11, 12, 13, 14, 15, 16, 17, 18}))
assert.Error(err).IsNil()
assert.Bytes(buffer.Value).Equals([]byte{0, 8, 39, 228, 69, 96, 133, 39, 254, 26, 201, 70, 11, 12, 13, 14, 15, 16, 17, 18})
assert.Bytes(buffer.Bytes()).Equals([]byte{0, 8, 39, 228, 69, 96, 133, 39, 254, 26, 201, 70, 11, 12, 13, 14, 15, 16, 17, 18})
}

View File

@ -32,12 +32,12 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
defer buffer.Release()
ivLen := account.Cipher.IVSize()
_, err = io.ReadFull(reader, buffer.Value[:ivLen])
_, err = io.ReadFull(reader, buffer.Bytes()[:ivLen])
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IV.")
}
iv := append([]byte(nil), buffer.Value[:ivLen]...)
iv := append([]byte(nil), buffer.Bytes()[:ivLen]...)
stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
if err != nil {
@ -53,13 +53,13 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
}
lenBuffer := 1
_, err = io.ReadFull(reader, buffer.Value[:1])
_, err = io.ReadFull(reader, buffer.Bytes()[:1])
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read address type.")
}
addrType := (buffer.Value[0] & 0x0F)
if (buffer.Value[0] & 0x10) == 0x10 {
addrType := (buffer.Bytes()[0] & 0x0F)
if (buffer.Bytes()[0] & 0x10) == 0x10 {
request.Option |= RequestOptionOneTimeAuth
}
@ -73,52 +73,52 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
switch addrType {
case AddrTypeIPv4:
_, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+4])
_, err := io.ReadFull(reader, buffer.BytesRange(lenBuffer, lenBuffer+4))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IPv4 address.")
}
request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+4])
request.Address = v2net.IPAddress(buffer.BytesRange(lenBuffer, lenBuffer+4))
lenBuffer += 4
case AddrTypeIPv6:
_, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+16])
_, err := io.ReadFull(reader, buffer.BytesRange(lenBuffer, lenBuffer+16))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IPv6 address.")
}
request.Address = v2net.IPAddress(buffer.Value[lenBuffer : lenBuffer+16])
request.Address = v2net.IPAddress(buffer.BytesRange(lenBuffer, lenBuffer+16))
lenBuffer += 16
case AddrTypeDomain:
_, err := io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+1])
_, err := io.ReadFull(reader, buffer.BytesRange(lenBuffer, lenBuffer+1))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read domain lenth.")
}
domainLength := int(buffer.Value[lenBuffer])
domainLength := int(buffer.Bytes()[lenBuffer])
lenBuffer++
_, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+domainLength])
_, err = io.ReadFull(reader, buffer.BytesRange(lenBuffer, lenBuffer+domainLength))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read domain.")
}
request.Address = v2net.DomainAddress(string(buffer.Value[lenBuffer : lenBuffer+domainLength]))
request.Address = v2net.DomainAddress(string(buffer.BytesRange(lenBuffer, lenBuffer+domainLength)))
lenBuffer += domainLength
default:
return nil, nil, errors.New("Shadowsocks|TCP: Unknown address type: ", addrType)
}
_, err = io.ReadFull(reader, buffer.Value[lenBuffer:lenBuffer+2])
_, err = io.ReadFull(reader, buffer.BytesRange(lenBuffer, lenBuffer+2))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read port.")
}
request.Port = v2net.PortFromBytes(buffer.Value[lenBuffer : lenBuffer+2])
request.Port = v2net.PortFromBytes(buffer.BytesRange(lenBuffer, lenBuffer+2))
lenBuffer += 2
if request.Option.Has(RequestOptionOneTimeAuth) {
authBytes := buffer.Value[lenBuffer : lenBuffer+AuthSize]
authBytes := buffer.BytesRange(lenBuffer, lenBuffer+AuthSize)
_, err = io.ReadFull(reader, authBytes)
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read OTA.")
}
actualAuth := authenticator.Authenticate(nil, buffer.Value[0:lenBuffer])
actualAuth := authenticator.Authenticate(nil, buffer.BytesTo(lenBuffer))
if !bytes.Equal(actualAuth, authBytes) {
return nil, nil, errors.New("Shadowsocks|TCP: Invalid OTA")
}
@ -175,7 +175,7 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (v2io.Wr
header.AppendUint16(uint16(request.Port))
if request.Option.Has(RequestOptionOneTimeAuth) {
header.Value[0] |= 0x10
header.Bytes()[0] |= 0x10
authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
header.Value = authenticator.Authenticate(header.Value, header.Value)

View File

@ -35,7 +35,7 @@ func TestUDPEncoding(t *testing.T) {
decodedRequest, decodedData, err := DecodeUDPPacket(request.User, encodedData)
assert.Error(err).IsNil()
assert.Bytes(decodedData.Value).Equals(data.Value)
assert.Bytes(decodedData.Bytes()).Equals(data.Bytes())
assert.Address(decodedRequest.Address).Equals(request.Address)
assert.Port(decodedRequest.Port).Equals(request.Port)
}
@ -73,7 +73,7 @@ func TestTCPRequest(t *testing.T) {
decodedData, err := reader.Read()
assert.Error(err).IsNil()
assert.Bytes(decodedData.Value).Equals([]byte("test string"))
assert.String(decodedData.String()).Equals("test string")
}
func TestUDPReaderWriter(t *testing.T) {

View File

@ -139,7 +139,7 @@ func (v *Server) handlerUDPPayload(payload *alloc.Buffer, session *proxy.Session
}
defer data.Release()
v.udpHub.WriteTo(data.Value, source)
v.udpHub.WriteTo(data.Bytes(), source)
})
}

View File

@ -95,7 +95,7 @@ func TestResponseWrite(t *testing.T) {
0x72, 0x72, 0x72, 0x72,
byte(0x00), byte(0x035),
}
assert.Bytes(buffer.Value).Equals(expectedBytes)
assert.Bytes(buffer.Bytes()).Equals(expectedBytes)
}
func TestSetIPv6(t *testing.T) {
@ -107,7 +107,7 @@ func TestSetIPv6(t *testing.T) {
buffer := alloc.NewLocalBuffer(2048).Clear()
defer buffer.Release()
response.Write(buffer)
assert.Bytes(buffer.Value).Equals([]byte{
assert.Bytes(buffer.Bytes()).Equals([]byte{
socksVersion, 0, 0, AddrTypeIPv6, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0})
}
@ -120,7 +120,7 @@ func TestSetDomain(t *testing.T) {
buffer := alloc.NewLocalBuffer(2048).Clear()
defer buffer.Release()
response.Write(buffer)
assert.Bytes(buffer.Value).Equals([]byte{
assert.Bytes(buffer.Bytes()).Equals([]byte{
socksVersion, 0, 0, AddrTypeDomain, 9, 118, 50, 114, 97, 121, 46, 99, 111, 109, 0, 0})
}