mirror of https://github.com/v2ray/v2ray-core
refine buffer usage
parent
9ecf89657c
commit
cf3eb0e77d
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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})
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue