mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-30 05:56:54 -05:00
simplify buffer extension
This commit is contained in:
parent
35ccc3a49c
commit
f7b96507f9
@ -39,9 +39,10 @@ func (r *cachedReader) Cache(b *buf.Buffer) {
|
|||||||
if !mb.IsEmpty() {
|
if !mb.IsEmpty() {
|
||||||
common.Must(r.cache.WriteMultiBuffer(mb))
|
common.Must(r.cache.WriteMultiBuffer(mb))
|
||||||
}
|
}
|
||||||
common.Must(b.Reset(func(x []byte) (int, error) {
|
b.Clear()
|
||||||
return r.cache.Copy(x), nil
|
rawBytes := b.Extend(buf.Size)
|
||||||
}))
|
n := r.cache.Copy(rawBytes)
|
||||||
|
b.Resize(0, int32(n))
|
||||||
r.Unlock()
|
r.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,13 +260,13 @@ func (s *ClassicNameServer) buildMsgs(domain string) []*dns.Msg {
|
|||||||
|
|
||||||
func msgToBuffer(msg *dns.Msg) (*buf.Buffer, error) {
|
func msgToBuffer(msg *dns.Msg) (*buf.Buffer, error) {
|
||||||
buffer := buf.New()
|
buffer := buf.New()
|
||||||
if err := buffer.Reset(func(b []byte) (int, error) {
|
rawBytes := buffer.Extend(buf.Size)
|
||||||
writtenBuffer, err := msg.PackBuffer(b)
|
packed, err := msg.PackBuffer(rawBytes)
|
||||||
return len(writtenBuffer), err
|
if err != nil {
|
||||||
}); err != nil {
|
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
buffer.Resize(0, int32(len(packed)))
|
||||||
return buffer, nil
|
return buffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,9 +11,6 @@ const (
|
|||||||
Size = 2048
|
Size = 2048
|
||||||
)
|
)
|
||||||
|
|
||||||
// Supplier is a writer that writes contents into the given buffer.
|
|
||||||
type Supplier func([]byte) (int, error)
|
|
||||||
|
|
||||||
// Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles
|
// Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles
|
||||||
// the buffer into an internal buffer pool, in order to recreate a buffer more
|
// the buffer into an internal buffer pool, in order to recreate a buffer more
|
||||||
// quickly.
|
// quickly.
|
||||||
@ -40,13 +37,6 @@ func (b *Buffer) Clear() {
|
|||||||
b.end = 0
|
b.end = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendSupplier appends the content of a BytesWriter to the buffer.
|
|
||||||
func (b *Buffer) AppendSupplier(writer Supplier) error {
|
|
||||||
nBytes, err := writer(b.v[b.end:])
|
|
||||||
b.end += int32(nBytes)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Byte returns the bytes at index.
|
// Byte returns the bytes at index.
|
||||||
func (b *Buffer) Byte(index int32) byte {
|
func (b *Buffer) Byte(index int32) byte {
|
||||||
return b.v[b.start+index]
|
return b.v[b.start+index]
|
||||||
@ -62,15 +52,16 @@ func (b *Buffer) Bytes() []byte {
|
|||||||
return b.v[b.start:b.end]
|
return b.v[b.start:b.end]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset resets the content of the Buffer with a supplier.
|
// Extend increases the buffer size by n bytes, and returns the extended part.
|
||||||
func (b *Buffer) Reset(writer Supplier) error {
|
// It panics if result size is larger than buf.Size.
|
||||||
nBytes, err := writer(b.v)
|
func (b *Buffer) Extend(n int32) []byte {
|
||||||
if nBytes > len(b.v) {
|
end := b.end + n
|
||||||
return newError("too many bytes written: ", nBytes, " > ", len(b.v))
|
if end > int32(len(b.v)) {
|
||||||
|
panic(newError("out of bound: ", end))
|
||||||
}
|
}
|
||||||
b.start = 0
|
ext := b.v[b.end:end]
|
||||||
b.end = int32(nBytes)
|
b.end = end
|
||||||
return err
|
return ext
|
||||||
}
|
}
|
||||||
|
|
||||||
// BytesRange returns a slice of this buffer with given from and to boundary.
|
// BytesRange returns a slice of this buffer with given from and to boundary.
|
||||||
@ -153,6 +144,11 @@ func (b *Buffer) WriteBytes(bytes ...byte) (int, error) {
|
|||||||
return b.Write(bytes)
|
return b.Write(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteString implements io.StringWriter.
|
||||||
|
func (b *Buffer) WriteString(s string) (int, error) {
|
||||||
|
return b.Write([]byte(s))
|
||||||
|
}
|
||||||
|
|
||||||
// Read implements io.Reader.Read().
|
// Read implements io.Reader.Read().
|
||||||
func (b *Buffer) Read(data []byte) (int, error) {
|
func (b *Buffer) Read(data []byte) (int, error) {
|
||||||
if b.Len() == 0 {
|
if b.Len() == 0 {
|
||||||
@ -174,6 +170,7 @@ func (b *Buffer) ReadFrom(reader io.Reader) (int64, error) {
|
|||||||
return int64(n), err
|
return int64(n), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadFullFrom reads exact size of bytes from given reader, or until error occurs.
|
||||||
func (b *Buffer) ReadFullFrom(reader io.Reader, size int32) (int64, error) {
|
func (b *Buffer) ReadFullFrom(reader io.Reader, size int32) (int64, error) {
|
||||||
end := b.end + size
|
end := b.end + size
|
||||||
if end > int32(len(b.v)) {
|
if end > int32(len(b.v)) {
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
. "v2ray.com/core/common/buf"
|
. "v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/compare"
|
"v2ray.com/core/common/compare"
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
. "v2ray.com/ext/assert"
|
. "v2ray.com/ext/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,7 +40,7 @@ func TestBufferString(t *testing.T) {
|
|||||||
buffer := New()
|
buffer := New()
|
||||||
defer buffer.Release()
|
defer buffer.Release()
|
||||||
|
|
||||||
assert(buffer.AppendSupplier(serial.WriteString("Test String")), IsNil)
|
common.Must2(buffer.WriteString("Test String"))
|
||||||
assert(buffer.String(), Equals, "Test String")
|
assert(buffer.String(), Equals, "Test String")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,10 +245,10 @@ func NewAuthenticationWriter(auth Authenticator, sizeParser ChunkSizeEncoder, wr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *AuthenticationWriter) seal(b *buf.Buffer) (*buf.Buffer, error) {
|
func (w *AuthenticationWriter) seal(b *buf.Buffer) (*buf.Buffer, error) {
|
||||||
encryptedSize := int(b.Len()) + w.auth.Overhead()
|
encryptedSize := b.Len() + int32(w.auth.Overhead())
|
||||||
var paddingSize int
|
var paddingSize int32
|
||||||
if w.padding != nil {
|
if w.padding != nil {
|
||||||
paddingSize = int(w.padding.NextPaddingLen())
|
paddingSize = int32(w.padding.NextPaddingLen())
|
||||||
}
|
}
|
||||||
|
|
||||||
totalSize := encryptedSize + paddingSize
|
totalSize := encryptedSize + paddingSize
|
||||||
@ -257,14 +257,8 @@ func (w *AuthenticationWriter) seal(b *buf.Buffer) (*buf.Buffer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
eb := buf.New()
|
eb := buf.New()
|
||||||
common.Must(eb.Reset(func(bb []byte) (int, error) {
|
w.sizeParser.Encode(uint16(encryptedSize+paddingSize), eb.Extend(w.sizeParser.SizeBytes()))
|
||||||
w.sizeParser.Encode(uint16(encryptedSize+paddingSize), bb)
|
if _, err := w.auth.Seal(eb.Extend(encryptedSize)[:0], b.Bytes()); err != nil {
|
||||||
return int(w.sizeParser.SizeBytes()), nil
|
|
||||||
}))
|
|
||||||
if err := eb.AppendSupplier(func(bb []byte) (int, error) {
|
|
||||||
_, err := w.auth.Seal(bb[:0], b.Bytes())
|
|
||||||
return encryptedSize, err
|
|
||||||
}); err != nil {
|
|
||||||
eb.Release()
|
eb.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -146,10 +146,7 @@ func (w *ChunkStreamWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
|||||||
slice := mb.SliceBySize(sliceSize)
|
slice := mb.SliceBySize(sliceSize)
|
||||||
|
|
||||||
b := buf.New()
|
b := buf.New()
|
||||||
common.Must(b.Reset(func(buffer []byte) (int, error) {
|
w.sizeEncoder.Encode(uint16(slice.Len()), b.Extend(w.sizeEncoder.SizeBytes()))
|
||||||
w.sizeEncoder.Encode(uint16(slice.Len()), buffer)
|
|
||||||
return int(w.sizeEncoder.SizeBytes()), nil
|
|
||||||
}))
|
|
||||||
mb2Write.Append(b)
|
mb2Write.Append(b)
|
||||||
mb2Write.AppendMulti(slice)
|
mb2Write.AppendMulti(slice)
|
||||||
|
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
package serial
|
|
||||||
|
|
||||||
import (
|
|
||||||
"hash"
|
|
||||||
)
|
|
||||||
|
|
||||||
func WriteHash(h hash.Hash) func(b []byte) (int, error) {
|
|
||||||
return func(b []byte) (int, error) {
|
|
||||||
h.Sum(b[:0])
|
|
||||||
return h.Size(), nil
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,6 @@ package blackhole
|
|||||||
import (
|
import (
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -28,7 +27,7 @@ func (*NoneResponse) WriteTo(buf.Writer) int32 { return 0 }
|
|||||||
// WriteTo implements ResponseConfig.WriteTo().
|
// WriteTo implements ResponseConfig.WriteTo().
|
||||||
func (*HTTPResponse) WriteTo(writer buf.Writer) int32 {
|
func (*HTTPResponse) WriteTo(writer buf.Writer) int32 {
|
||||||
b := buf.New()
|
b := buf.New()
|
||||||
common.Must(b.Reset(serial.WriteString(http403response)))
|
common.Must2(b.Write([]byte(http403response)))
|
||||||
n := b.Len()
|
n := b.Len()
|
||||||
writer.WriteMultiBuffer(buf.NewMultiBufferValue(b))
|
writer.WriteMultiBuffer(buf.NewMultiBufferValue(b))
|
||||||
return n
|
return n
|
||||||
|
@ -198,13 +198,10 @@ func (c *AEADCipher) EncodePacket(key []byte, b *buf.Buffer) error {
|
|||||||
ivLen := c.IVSize()
|
ivLen := c.IVSize()
|
||||||
payloadLen := b.Len()
|
payloadLen := b.Len()
|
||||||
auth := c.createAuthenticator(key, b.BytesTo(ivLen))
|
auth := c.createAuthenticator(key, b.BytesTo(ivLen))
|
||||||
return b.Reset(func(bb []byte) (int, error) {
|
|
||||||
bbb, err := auth.Seal(bb[:ivLen], bb[ivLen:payloadLen])
|
b.Extend(int32(auth.Overhead()))
|
||||||
if err != nil {
|
_, err := auth.Seal(b.BytesTo(ivLen), b.BytesRange(ivLen, payloadLen))
|
||||||
return 0, err
|
return err
|
||||||
}
|
|
||||||
return len(bbb), nil
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *AEADCipher) DecodePacket(key []byte, b *buf.Buffer) error {
|
func (c *AEADCipher) DecodePacket(key []byte, b *buf.Buffer) error {
|
||||||
@ -214,16 +211,12 @@ func (c *AEADCipher) DecodePacket(key []byte, b *buf.Buffer) error {
|
|||||||
ivLen := c.IVSize()
|
ivLen := c.IVSize()
|
||||||
payloadLen := b.Len()
|
payloadLen := b.Len()
|
||||||
auth := c.createAuthenticator(key, b.BytesTo(ivLen))
|
auth := c.createAuthenticator(key, b.BytesTo(ivLen))
|
||||||
if err := b.Reset(func(bb []byte) (int, error) {
|
|
||||||
bbb, err := auth.Open(bb[:ivLen], bb[ivLen:payloadLen])
|
bbb, err := auth.Open(b.BytesTo(ivLen), b.BytesRange(ivLen, payloadLen))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return len(bbb), nil
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
b.Advance(ivLen)
|
b.Resize(ivLen, ivLen+int32(len(bbb)))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,13 +30,11 @@ func NewAuthenticator(keygen KeyGenerator) *Authenticator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Authenticator) Authenticate(data []byte) buf.Supplier {
|
func (v *Authenticator) Authenticate(data []byte, dest []byte) {
|
||||||
hasher := hmac.New(sha1.New, v.key())
|
hasher := hmac.New(sha1.New, v.key())
|
||||||
common.Must2(hasher.Write(data))
|
common.Must2(hasher.Write(data))
|
||||||
res := hasher.Sum(nil)
|
res := hasher.Sum(nil)
|
||||||
return func(b []byte) (int, error) {
|
copy(dest, res[:AuthSize])
|
||||||
return copy(b, res[:AuthSize]), nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func HeaderKeyGenerator(key []byte, iv []byte) func() []byte {
|
func HeaderKeyGenerator(key []byte, iv []byte) func() []byte {
|
||||||
@ -89,7 +87,7 @@ func (v *ChunkReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||||||
payload := buffer[AuthSize:size]
|
payload := buffer[AuthSize:size]
|
||||||
|
|
||||||
actualAuthBytes := make([]byte, AuthSize)
|
actualAuthBytes := make([]byte, AuthSize)
|
||||||
v.auth.Authenticate(payload)(actualAuthBytes)
|
v.auth.Authenticate(payload, actualAuthBytes)
|
||||||
if !bytes.Equal(authBytes, actualAuthBytes) {
|
if !bytes.Equal(authBytes, actualAuthBytes) {
|
||||||
return nil, newError("invalid auth")
|
return nil, newError("invalid auth")
|
||||||
}
|
}
|
||||||
@ -121,7 +119,7 @@ func (w *ChunkWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
|||||||
for {
|
for {
|
||||||
payloadLen, _ := mb.Read(w.buffer[2+AuthSize:])
|
payloadLen, _ := mb.Read(w.buffer[2+AuthSize:])
|
||||||
binary.BigEndian.PutUint16(w.buffer, uint16(payloadLen))
|
binary.BigEndian.PutUint16(w.buffer, uint16(payloadLen))
|
||||||
w.auth.Authenticate(w.buffer[2+AuthSize : 2+AuthSize+payloadLen])(w.buffer[2:])
|
w.auth.Authenticate(w.buffer[2+AuthSize:2+AuthSize+payloadLen], w.buffer[2:])
|
||||||
if err := buf.WriteAllBytes(w.writer, w.buffer[:2+AuthSize+payloadLen]); err != nil {
|
if err := buf.WriteAllBytes(w.writer, w.buffer[:2+AuthSize+payloadLen]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,8 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
|
|||||||
header.SetByte(0, header.Byte(0)|0x10)
|
header.SetByte(0, header.Byte(0)|0x10)
|
||||||
|
|
||||||
authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
|
authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
|
||||||
common.Must(header.AppendSupplier(authenticator.Authenticate(header.Bytes())))
|
authBuffer := header.Extend(AuthSize)
|
||||||
|
authenticator.Authenticate(header.Bytes(), authBuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := w.WriteMultiBuffer(buf.NewMultiBufferValue(header)); err != nil {
|
if err := w.WriteMultiBuffer(buf.NewMultiBufferValue(header)); err != nil {
|
||||||
@ -210,7 +211,9 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload []byte) (*buf.Buff
|
|||||||
authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
|
authenticator := NewAuthenticator(HeaderKeyGenerator(account.Key, iv))
|
||||||
buffer.SetByte(ivLen, buffer.Byte(ivLen)|0x10)
|
buffer.SetByte(ivLen, buffer.Byte(ivLen)|0x10)
|
||||||
|
|
||||||
common.Must(buffer.AppendSupplier(authenticator.Authenticate(buffer.BytesFrom(ivLen))))
|
authPayload := buffer.BytesFrom(ivLen)
|
||||||
|
authBuffer := buffer.Extend(AuthSize)
|
||||||
|
authenticator.Authenticate(authPayload, authBuffer)
|
||||||
}
|
}
|
||||||
if err := account.Cipher.EncodePacket(account.Key, buffer); err != nil {
|
if err := account.Cipher.EncodePacket(account.Key, buffer); err != nil {
|
||||||
return nil, newError("failed to encrypt UDP payload").Base(err)
|
return nil, newError("failed to encrypt UDP payload").Base(err)
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/common/protocol"
|
"v2ray.com/core/common/protocol"
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
. "v2ray.com/core/proxy/shadowsocks"
|
. "v2ray.com/core/proxy/shadowsocks"
|
||||||
. "v2ray.com/ext/assert"
|
. "v2ray.com/ext/assert"
|
||||||
)
|
)
|
||||||
@ -37,7 +36,7 @@ func TestUDPEncoding(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data := buf.New()
|
data := buf.New()
|
||||||
data.AppendSupplier(serial.WriteString("test string"))
|
common.Must2(data.WriteString("test string"))
|
||||||
encodedData, err := EncodeUDPPacket(request, data.Bytes())
|
encodedData, err := EncodeUDPPacket(request, data.Bytes())
|
||||||
assert(err, IsNil)
|
assert(err, IsNil)
|
||||||
|
|
||||||
@ -168,7 +167,7 @@ func TestUDPReaderWriter(t *testing.T) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
b := buf.New()
|
b := buf.New()
|
||||||
b.AppendSupplier(serial.WriteString("test payload"))
|
common.Must2(b.WriteString("test payload"))
|
||||||
err := writer.WriteMultiBuffer(buf.NewMultiBufferValue(b))
|
err := writer.WriteMultiBuffer(buf.NewMultiBufferValue(b))
|
||||||
assert(err, IsNil)
|
assert(err, IsNil)
|
||||||
|
|
||||||
@ -179,7 +178,7 @@ func TestUDPReaderWriter(t *testing.T) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
b := buf.New()
|
b := buf.New()
|
||||||
b.AppendSupplier(serial.WriteString("test payload 2"))
|
common.Must2(b.WriteString("test payload 2"))
|
||||||
err := writer.WriteMultiBuffer(buf.NewMultiBufferValue(b))
|
err := writer.WriteMultiBuffer(buf.NewMultiBufferValue(b))
|
||||||
assert(err, IsNil)
|
assert(err, IsNil)
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ import (
|
|||||||
"v2ray.com/core/common/crypto"
|
"v2ray.com/core/common/crypto"
|
||||||
"v2ray.com/core/common/dice"
|
"v2ray.com/core/common/dice"
|
||||||
"v2ray.com/core/common/protocol"
|
"v2ray.com/core/common/protocol"
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
"v2ray.com/core/common/vio"
|
"v2ray.com/core/common/vio"
|
||||||
"v2ray.com/core/proxy/vmess"
|
"v2ray.com/core/proxy/vmess"
|
||||||
)
|
)
|
||||||
@ -88,7 +87,8 @@ func (c *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writ
|
|||||||
{
|
{
|
||||||
fnv1a := fnv.New32a()
|
fnv1a := fnv.New32a()
|
||||||
common.Must2(fnv1a.Write(buffer.Bytes()))
|
common.Must2(fnv1a.Write(buffer.Bytes()))
|
||||||
common.Must(buffer.AppendSupplier(serial.WriteHash(fnv1a)))
|
hashBytes := buffer.Extend(int32(fnv1a.Size()))
|
||||||
|
fnv1a.Sum(hashBytes[:0])
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := hashTimestamp(md5.New(), timestamp)
|
iv := hashTimestamp(md5.New(), timestamp)
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
type PacketHeader interface {
|
type PacketHeader interface {
|
||||||
Size() int32
|
Size() int32
|
||||||
Write([]byte) (int, error)
|
Serialize([]byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePacketHeader(config interface{}) (PacketHeader, error) {
|
func CreatePacketHeader(config interface{}) (PacketHeader, error) {
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
|
|
||||||
"v2ray.com/core/common"
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -29,7 +28,6 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
ErrHeaderToLong = newError("Header too long.")
|
ErrHeaderToLong = newError("Header too long.")
|
||||||
writeCRLF = serial.WriteString(CRLF)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Reader interface {
|
type Reader interface {
|
||||||
@ -70,12 +68,12 @@ func (*HeaderReader) Read(reader io.Reader) (*buf.Buffer, error) {
|
|||||||
endingDetected = true
|
endingDetected = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if buffer.Len() >= int32(len(ENDING)) {
|
lenEnding := int32(len(ENDING))
|
||||||
totalBytes += buffer.Len() - int32(len(ENDING))
|
if buffer.Len() >= lenEnding {
|
||||||
leftover := buffer.BytesFrom(-int32(len(ENDING)))
|
totalBytes += buffer.Len() - lenEnding
|
||||||
buffer.Reset(func(b []byte) (int, error) {
|
leftover := buffer.BytesFrom(-lenEnding)
|
||||||
return copy(b, leftover), nil
|
buffer.Clear()
|
||||||
})
|
copy(buffer.Extend(lenEnding), leftover)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if buffer.IsEmpty() {
|
if buffer.IsEmpty() {
|
||||||
@ -175,20 +173,20 @@ func (c *HttpConn) Close() error {
|
|||||||
|
|
||||||
func formResponseHeader(config *ResponseConfig) *HeaderWriter {
|
func formResponseHeader(config *ResponseConfig) *HeaderWriter {
|
||||||
header := buf.New()
|
header := buf.New()
|
||||||
header.AppendSupplier(serial.WriteString(strings.Join([]string{config.GetFullVersion(), config.GetStatusValue().Code, config.GetStatusValue().Reason}, " ")))
|
common.Must2(header.WriteString(strings.Join([]string{config.GetFullVersion(), config.GetStatusValue().Code, config.GetStatusValue().Reason}, " ")))
|
||||||
header.AppendSupplier(writeCRLF)
|
common.Must2(header.WriteString(CRLF))
|
||||||
|
|
||||||
headers := config.PickHeaders()
|
headers := config.PickHeaders()
|
||||||
for _, h := range headers {
|
for _, h := range headers {
|
||||||
header.AppendSupplier(serial.WriteString(h))
|
common.Must2(header.WriteString(h))
|
||||||
header.AppendSupplier(writeCRLF)
|
common.Must2(header.WriteString(CRLF))
|
||||||
}
|
}
|
||||||
if !config.HasHeader("Date") {
|
if !config.HasHeader("Date") {
|
||||||
header.AppendSupplier(serial.WriteString("Date: "))
|
common.Must2(header.WriteString("Date: "))
|
||||||
header.AppendSupplier(serial.WriteString(time.Now().Format(http.TimeFormat)))
|
common.Must2(header.WriteString(time.Now().Format(http.TimeFormat)))
|
||||||
header.AppendSupplier(writeCRLF)
|
common.Must2(header.WriteString(CRLF))
|
||||||
}
|
}
|
||||||
header.AppendSupplier(writeCRLF)
|
common.Must2(header.WriteString(CRLF))
|
||||||
return &HeaderWriter{
|
return &HeaderWriter{
|
||||||
header: header,
|
header: header,
|
||||||
}
|
}
|
||||||
@ -201,15 +199,15 @@ type HttpAuthenticator struct {
|
|||||||
func (a HttpAuthenticator) GetClientWriter() *HeaderWriter {
|
func (a HttpAuthenticator) GetClientWriter() *HeaderWriter {
|
||||||
header := buf.New()
|
header := buf.New()
|
||||||
config := a.config.Request
|
config := a.config.Request
|
||||||
header.AppendSupplier(serial.WriteString(strings.Join([]string{config.GetMethodValue(), config.PickUri(), config.GetFullVersion()}, " ")))
|
common.Must2(header.WriteString(strings.Join([]string{config.GetMethodValue(), config.PickUri(), config.GetFullVersion()}, " ")))
|
||||||
header.AppendSupplier(writeCRLF)
|
common.Must2(header.WriteString(CRLF))
|
||||||
|
|
||||||
headers := config.PickHeaders()
|
headers := config.PickHeaders()
|
||||||
for _, h := range headers {
|
for _, h := range headers {
|
||||||
header.AppendSupplier(serial.WriteString(h))
|
common.Must2(header.WriteString(h))
|
||||||
header.AppendSupplier(writeCRLF)
|
common.Must2(header.WriteString(CRLF))
|
||||||
}
|
}
|
||||||
header.AppendSupplier(writeCRLF)
|
common.Must2(header.WriteString(CRLF))
|
||||||
return &HeaderWriter{
|
return &HeaderWriter{
|
||||||
header: header,
|
header: header,
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"v2ray.com/core/common"
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
"v2ray.com/core/common/net"
|
"v2ray.com/core/common/net"
|
||||||
"v2ray.com/core/common/serial"
|
|
||||||
. "v2ray.com/core/transport/internet/headers/http"
|
. "v2ray.com/core/transport/internet/headers/http"
|
||||||
. "v2ray.com/ext/assert"
|
. "v2ray.com/ext/assert"
|
||||||
)
|
)
|
||||||
@ -17,7 +17,7 @@ func TestReaderWriter(t *testing.T) {
|
|||||||
|
|
||||||
cache := buf.New()
|
cache := buf.New()
|
||||||
b := buf.New()
|
b := buf.New()
|
||||||
b.AppendSupplier(serial.WriteString("abcd" + ENDING))
|
common.Must2(b.WriteString("abcd" + ENDING))
|
||||||
writer := NewHeaderWriter(b)
|
writer := NewHeaderWriter(b)
|
||||||
err := writer.Write(cache)
|
err := writer.Write(cache)
|
||||||
assert(err, IsNil)
|
assert(err, IsNil)
|
||||||
|
@ -13,10 +13,8 @@ func (NoOpHeader) Size() int32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements io.Writer.
|
// Serialize implements PacketHeader.
|
||||||
func (NoOpHeader) Write([]byte) (int, error) {
|
func (NoOpHeader) Serialize([]byte) {}
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNoOpHeader(context.Context, interface{}) (interface{}, error) {
|
func NewNoOpHeader(context.Context, interface{}) (interface{}, error) {
|
||||||
return NoOpHeader{}, nil
|
return NoOpHeader{}, nil
|
||||||
|
@ -17,12 +17,11 @@ func (*SRTP) Size() int32 {
|
|||||||
return 4
|
return 4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements io.Writer.
|
// Serialize implements PacketHeader.
|
||||||
func (s *SRTP) Write(b []byte) (int, error) {
|
func (s *SRTP) Serialize(b []byte) {
|
||||||
s.number++
|
s.number++
|
||||||
binary.BigEndian.PutUint16(b, s.number)
|
binary.BigEndian.PutUint16(b, s.number)
|
||||||
binary.BigEndian.PutUint16(b[2:], s.number)
|
binary.BigEndian.PutUint16(b[2:], s.number)
|
||||||
return 4, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new SRTP instance based on the given config.
|
// New returns a new SRTP instance based on the given config.
|
||||||
|
@ -19,7 +19,7 @@ func TestSRTPWrite(t *testing.T) {
|
|||||||
srtp := srtpRaw.(*SRTP)
|
srtp := srtpRaw.(*SRTP)
|
||||||
|
|
||||||
payload := buf.New()
|
payload := buf.New()
|
||||||
payload.AppendSupplier(srtp.Write)
|
srtp.Serialize(payload.Extend(srtp.Size()))
|
||||||
payload.Write(content)
|
payload.Write(content)
|
||||||
|
|
||||||
assert(payload.Len(), Equals, int32(len(content))+srtp.Size())
|
assert(payload.Len(), Equals, int32(len(content))+srtp.Size())
|
||||||
|
@ -19,8 +19,8 @@ func (*DTLS) Size() int32 {
|
|||||||
return 1 + 2 + 2 + 6 + 2
|
return 1 + 2 + 2 + 6 + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements PacketHeader.
|
// Serialize implements PacketHeader.
|
||||||
func (d *DTLS) Write(b []byte) (int, error) {
|
func (d *DTLS) Serialize(b []byte) {
|
||||||
b[0] = 23 // application data
|
b[0] = 23 // application data
|
||||||
b[1] = 254
|
b[1] = 254
|
||||||
b[2] = 253
|
b[2] = 253
|
||||||
@ -39,7 +39,6 @@ func (d *DTLS) Write(b []byte) (int, error) {
|
|||||||
if d.length > 100 {
|
if d.length > 100 {
|
||||||
d.length -= 50
|
d.length -= 50
|
||||||
}
|
}
|
||||||
return 13, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new UTP header for the given config.
|
// New creates a new UTP header for the given config.
|
||||||
|
@ -19,7 +19,7 @@ func TestDTLSWrite(t *testing.T) {
|
|||||||
dtls := dtlsRaw.(*DTLS)
|
dtls := dtlsRaw.(*DTLS)
|
||||||
|
|
||||||
payload := buf.New()
|
payload := buf.New()
|
||||||
payload.AppendSupplier(dtls.Write)
|
dtls.Serialize(payload.Extend(dtls.Size()))
|
||||||
payload.Write(content)
|
payload.Write(content)
|
||||||
|
|
||||||
assert(payload.Len(), Equals, int32(len(content))+dtls.Size())
|
assert(payload.Len(), Equals, int32(len(content))+dtls.Size())
|
||||||
|
@ -18,12 +18,11 @@ func (*UTP) Size() int32 {
|
|||||||
return 4
|
return 4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements io.Writer.
|
// Serialize implements PacketHeader.
|
||||||
func (u *UTP) Write(b []byte) (int, error) {
|
func (u *UTP) Serialize(b []byte) {
|
||||||
binary.BigEndian.PutUint16(b, u.connectionId)
|
binary.BigEndian.PutUint16(b, u.connectionId)
|
||||||
b[2] = u.header
|
b[2] = u.header
|
||||||
b[3] = u.extension
|
b[3] = u.extension
|
||||||
return 4, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new UTP header for the given config.
|
// New creates a new UTP header for the given config.
|
||||||
|
@ -19,7 +19,7 @@ func TestUTPWrite(t *testing.T) {
|
|||||||
utp := utpRaw.(*UTP)
|
utp := utpRaw.(*UTP)
|
||||||
|
|
||||||
payload := buf.New()
|
payload := buf.New()
|
||||||
payload.AppendSupplier(utp.Write)
|
utp.Serialize(payload.Extend(utp.Size()))
|
||||||
payload.Write(content)
|
payload.Write(content)
|
||||||
|
|
||||||
assert(payload.Len(), Equals, int32(len(content))+utp.Size())
|
assert(payload.Len(), Equals, int32(len(content))+utp.Size())
|
||||||
|
@ -16,8 +16,8 @@ func (vc *VideoChat) Size() int32 {
|
|||||||
return 13
|
return 13
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements io.Writer.
|
// Serialize implements PacketHeader.
|
||||||
func (vc *VideoChat) Write(b []byte) (int, error) {
|
func (vc *VideoChat) Serialize(b []byte) {
|
||||||
vc.sn++
|
vc.sn++
|
||||||
b[0] = 0xa1
|
b[0] = 0xa1
|
||||||
b[1] = 0x08
|
b[1] = 0x08
|
||||||
@ -29,7 +29,6 @@ func (vc *VideoChat) Write(b []byte) (int, error) {
|
|||||||
b[10] = 0x30
|
b[10] = 0x30
|
||||||
b[11] = 0x22
|
b[11] = 0x22
|
||||||
b[12] = 0x30
|
b[12] = 0x30
|
||||||
return 13, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewVideoChat returns a new VideoChat instance based on given config.
|
// NewVideoChat returns a new VideoChat instance based on given config.
|
||||||
|
@ -18,7 +18,7 @@ func TestUTPWrite(t *testing.T) {
|
|||||||
video := videoRaw.(*VideoChat)
|
video := videoRaw.(*VideoChat)
|
||||||
|
|
||||||
payload := buf.New()
|
payload := buf.New()
|
||||||
payload.AppendSupplier(video.Write)
|
video.Serialize(payload.Extend(video.Size()))
|
||||||
|
|
||||||
assert(payload.Len(), Equals, video.Size())
|
assert(payload.Len(), Equals, video.Size())
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,12 @@ func (Wireguard) Size() int32 {
|
|||||||
return 4
|
return 4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write implements io.Writer.
|
// Serialize implements PacketHeader.
|
||||||
func (Wireguard) Write(b []byte) (int, error) {
|
func (Wireguard) Serialize(b []byte) {
|
||||||
b = append(b[:0], 0x04, 0x00, 0x00, 0x00)
|
b[0] = 0x04
|
||||||
return 4, nil
|
b[1] = 0x00
|
||||||
|
b[2] = 0x00
|
||||||
|
b[3] = 0x00
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWireguard returns a new VideoChat instance based on given config.
|
// NewWireguard returns a new VideoChat instance based on given config.
|
||||||
|
@ -74,20 +74,15 @@ func (w *KCPPacketWriter) Write(b []byte) (int, error) {
|
|||||||
defer bb.Release()
|
defer bb.Release()
|
||||||
|
|
||||||
if w.Header != nil {
|
if w.Header != nil {
|
||||||
common.Must(bb.AppendSupplier(func(x []byte) (int, error) {
|
w.Header.Serialize(bb.Extend(w.Header.Size()))
|
||||||
return w.Header.Write(x)
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
if w.Security != nil {
|
if w.Security != nil {
|
||||||
nonceSize := w.Security.NonceSize()
|
nonceSize := w.Security.NonceSize()
|
||||||
common.Must(bb.AppendSupplier(func(x []byte) (int, error) {
|
common.Must2(bb.ReadFullFrom(rand.Reader, int32(nonceSize)))
|
||||||
return rand.Read(x[:nonceSize])
|
|
||||||
}))
|
|
||||||
nonce := bb.BytesFrom(int32(-nonceSize))
|
nonce := bb.BytesFrom(int32(-nonceSize))
|
||||||
common.Must(bb.AppendSupplier(func(x []byte) (int, error) {
|
|
||||||
eb := w.Security.Seal(x[:0], nonce, b, nil)
|
encrypted := bb.Extend(int32(w.Security.Overhead() + len(b)))
|
||||||
return len(eb), nil
|
w.Security.Seal(encrypted[:0], nonce, b, nil)
|
||||||
}))
|
|
||||||
} else {
|
} else {
|
||||||
bb.Write(b)
|
bb.Write(b)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
|
|
||||||
"v2ray.com/core/common/retry"
|
"v2ray.com/core/common/retry"
|
||||||
|
|
||||||
"v2ray.com/core/common"
|
|
||||||
"v2ray.com/core/common/buf"
|
"v2ray.com/core/common/buf"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,7 +30,9 @@ func (w *SimpleSegmentWriter) Write(seg Segment) error {
|
|||||||
w.Lock()
|
w.Lock()
|
||||||
defer w.Unlock()
|
defer w.Unlock()
|
||||||
|
|
||||||
common.Must(w.buffer.Reset(seg.Bytes()))
|
w.buffer.Clear()
|
||||||
|
rawBytes := w.buffer.Extend(seg.ByteSize())
|
||||||
|
seg.Serialize(rawBytes)
|
||||||
_, err := w.writer.Write(w.buffer.Bytes())
|
_, err := w.writer.Write(w.buffer.Bytes())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ type Segment interface {
|
|||||||
Conversation() uint16
|
Conversation() uint16
|
||||||
Command() Command
|
Command() Command
|
||||||
ByteSize() int32
|
ByteSize() int32
|
||||||
Bytes() buf.Supplier
|
Serialize([]byte)
|
||||||
parse(conv uint16, cmd Command, opt SegmentOption, buf []byte) (bool, []byte)
|
parse(conv uint16, cmd Command, opt SegmentOption, buf []byte) (bool, []byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,18 +104,15 @@ func (s *DataSegment) Data() *buf.Buffer {
|
|||||||
return s.payload
|
return s.payload
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DataSegment) Bytes() buf.Supplier {
|
func (s *DataSegment) Serialize(b []byte) {
|
||||||
return func(b []byte) (int, error) {
|
binary.BigEndian.PutUint16(b, s.Conv)
|
||||||
binary.BigEndian.PutUint16(b, s.Conv)
|
b[2] = byte(CommandData)
|
||||||
b[2] = byte(CommandData)
|
b[3] = byte(s.Option)
|
||||||
b[3] = byte(s.Option)
|
binary.BigEndian.PutUint32(b[4:], s.Timestamp)
|
||||||
binary.BigEndian.PutUint32(b[4:], s.Timestamp)
|
binary.BigEndian.PutUint32(b[8:], s.Number)
|
||||||
binary.BigEndian.PutUint32(b[8:], s.Number)
|
binary.BigEndian.PutUint32(b[12:], s.SendingNext)
|
||||||
binary.BigEndian.PutUint32(b[12:], s.SendingNext)
|
binary.BigEndian.PutUint16(b[16:], uint16(s.payload.Len()))
|
||||||
binary.BigEndian.PutUint16(b[16:], uint16(s.payload.Len()))
|
copy(b[18:], s.payload.Bytes())
|
||||||
n := copy(b[18:], s.payload.Bytes())
|
|
||||||
return 18 + n, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DataSegment) ByteSize() int32 {
|
func (s *DataSegment) ByteSize() int32 {
|
||||||
@ -202,21 +199,18 @@ func (s *AckSegment) ByteSize() int32 {
|
|||||||
return 2 + 1 + 1 + 4 + 4 + 4 + 1 + int32(len(s.NumberList)*4)
|
return 2 + 1 + 1 + 4 + 4 + 4 + 1 + int32(len(s.NumberList)*4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AckSegment) Bytes() buf.Supplier {
|
func (s *AckSegment) Serialize(b []byte) {
|
||||||
return func(b []byte) (int, error) {
|
binary.BigEndian.PutUint16(b, s.Conv)
|
||||||
binary.BigEndian.PutUint16(b, s.Conv)
|
b[2] = byte(CommandACK)
|
||||||
b[2] = byte(CommandACK)
|
b[3] = byte(s.Option)
|
||||||
b[3] = byte(s.Option)
|
binary.BigEndian.PutUint32(b[4:], s.ReceivingWindow)
|
||||||
binary.BigEndian.PutUint32(b[4:], s.ReceivingWindow)
|
binary.BigEndian.PutUint32(b[8:], s.ReceivingNext)
|
||||||
binary.BigEndian.PutUint32(b[8:], s.ReceivingNext)
|
binary.BigEndian.PutUint32(b[12:], s.Timestamp)
|
||||||
binary.BigEndian.PutUint32(b[12:], s.Timestamp)
|
b[16] = byte(len(s.NumberList))
|
||||||
b[16] = byte(len(s.NumberList))
|
n := 17
|
||||||
n := 17
|
for _, number := range s.NumberList {
|
||||||
for _, number := range s.NumberList {
|
binary.BigEndian.PutUint32(b[n:], number)
|
||||||
binary.BigEndian.PutUint32(b[n:], number)
|
n += 4
|
||||||
n += 4
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,16 +262,13 @@ func (*CmdOnlySegment) ByteSize() int32 {
|
|||||||
return 2 + 1 + 1 + 4 + 4 + 4
|
return 2 + 1 + 1 + 4 + 4 + 4
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CmdOnlySegment) Bytes() buf.Supplier {
|
func (s *CmdOnlySegment) Serialize(b []byte) {
|
||||||
return func(b []byte) (int, error) {
|
binary.BigEndian.PutUint16(b, s.Conv)
|
||||||
binary.BigEndian.PutUint16(b, s.Conv)
|
b[2] = byte(s.Cmd)
|
||||||
b[2] = byte(s.Cmd)
|
b[3] = byte(s.Option)
|
||||||
b[3] = byte(s.Option)
|
binary.BigEndian.PutUint32(b[4:], s.SendingNext)
|
||||||
binary.BigEndian.PutUint32(b[4:], s.SendingNext)
|
binary.BigEndian.PutUint32(b[8:], s.ReceivingNext)
|
||||||
binary.BigEndian.PutUint32(b[8:], s.ReceivingNext)
|
binary.BigEndian.PutUint32(b[12:], s.PeerRTO)
|
||||||
binary.BigEndian.PutUint32(b[12:], s.PeerRTO)
|
|
||||||
return 16, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*CmdOnlySegment) Release() {}
|
func (*CmdOnlySegment) Release() {}
|
||||||
|
@ -28,7 +28,7 @@ func TestDataSegment(t *testing.T) {
|
|||||||
|
|
||||||
nBytes := seg.ByteSize()
|
nBytes := seg.ByteSize()
|
||||||
bytes := make([]byte, nBytes)
|
bytes := make([]byte, nBytes)
|
||||||
seg.Bytes()(bytes)
|
seg.Serialize(bytes)
|
||||||
|
|
||||||
assert(int32(len(bytes)), Equals, nBytes)
|
assert(int32(len(bytes)), Equals, nBytes)
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ func Test1ByteDataSegment(t *testing.T) {
|
|||||||
|
|
||||||
nBytes := seg.ByteSize()
|
nBytes := seg.ByteSize()
|
||||||
bytes := make([]byte, nBytes)
|
bytes := make([]byte, nBytes)
|
||||||
seg.Bytes()(bytes)
|
seg.Serialize(bytes)
|
||||||
|
|
||||||
assert(int32(len(bytes)), Equals, nBytes)
|
assert(int32(len(bytes)), Equals, nBytes)
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ func TestACKSegment(t *testing.T) {
|
|||||||
|
|
||||||
nBytes := seg.ByteSize()
|
nBytes := seg.ByteSize()
|
||||||
bytes := make([]byte, nBytes)
|
bytes := make([]byte, nBytes)
|
||||||
seg.Bytes()(bytes)
|
seg.Serialize(bytes)
|
||||||
|
|
||||||
assert(int32(len(bytes)), Equals, nBytes)
|
assert(int32(len(bytes)), Equals, nBytes)
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ func TestCmdSegment(t *testing.T) {
|
|||||||
|
|
||||||
nBytes := seg.ByteSize()
|
nBytes := seg.ByteSize()
|
||||||
bytes := make([]byte, nBytes)
|
bytes := make([]byte, nBytes)
|
||||||
seg.Bytes()(bytes)
|
seg.Serialize(bytes)
|
||||||
|
|
||||||
assert(int32(len(bytes)), Equals, nBytes)
|
assert(int32(len(bytes)), Equals, nBytes)
|
||||||
|
|
||||||
|
@ -88,18 +88,15 @@ func (h *Hub) start() {
|
|||||||
buffer := buf.New()
|
buffer := buf.New()
|
||||||
var noob int
|
var noob int
|
||||||
var addr *net.UDPAddr
|
var addr *net.UDPAddr
|
||||||
err := buffer.Reset(func(b []byte) (int, error) {
|
rawBytes := buffer.Extend(buf.Size)
|
||||||
n, nb, _, a, e := ReadUDPMsg(h.conn, b, oobBytes)
|
|
||||||
noob = nb
|
|
||||||
addr = a
|
|
||||||
return n, e
|
|
||||||
})
|
|
||||||
|
|
||||||
|
n, noob, _, addr, err := ReadUDPMsg(h.conn, rawBytes, oobBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
newError("failed to read UDP msg").Base(err).WriteToLog()
|
newError("failed to read UDP msg").Base(err).WriteToLog()
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
buffer.Resize(0, int32(n))
|
||||||
|
|
||||||
if buffer.IsEmpty() {
|
if buffer.IsEmpty() {
|
||||||
buffer.Release()
|
buffer.Release()
|
||||||
|
Loading…
Reference in New Issue
Block a user