diff --git a/common/protocol/address.go b/common/protocol/address.go index 51faf37e..4f80e6c9 100644 --- a/common/protocol/address.go +++ b/common/protocol/address.go @@ -2,11 +2,13 @@ package protocol import ( "io" + "unsafe" "v2ray.com/core/common" "v2ray.com/core/common/buf" "v2ray.com/core/common/net" "v2ray.com/core/common/serial" + "v2ray.com/core/common/stack" ) type AddressOption func(*option) @@ -232,7 +234,13 @@ func (p *addressParser) writeAddress(writer io.Writer, address net.Address) erro switch address.Family() { case net.AddressFamilyIPv4, net.AddressFamilyIPv6: - if _, err := writer.Write([]byte{tb}); err != nil { + var bytes stack.TwoBytes + s := bytes[:1] + s[0] = tb + p := uintptr(unsafe.Pointer(&s)) + v := (*[]byte)(unsafe.Pointer(p)) + + if _, err := writer.Write(*v); err != nil { return err } if _, err := writer.Write(address.IP()); err != nil { @@ -243,7 +251,15 @@ func (p *addressParser) writeAddress(writer io.Writer, address net.Address) erro if isDomainTooLong(domain) { return newError("Super long domain is not supported: ", domain) } - if _, err := writer.Write([]byte{tb, byte(len(domain))}); err != nil { + + var bytes stack.TwoBytes + s := bytes[:] + s[0] = tb + s[1] = byte(len(domain)) + p := uintptr(unsafe.Pointer(&s)) + v := (*[]byte)(unsafe.Pointer(p)) + + if _, err := writer.Write(*v); err != nil { return err } if _, err := io.WriteString(writer, domain); err != nil { diff --git a/common/stack/bytes.go b/common/stack/bytes.go new file mode 100644 index 00000000..0ea5631b --- /dev/null +++ b/common/stack/bytes.go @@ -0,0 +1,11 @@ +package stack + +// TwoBytes is a [8]byte which is always allocated on stack. +// +//go:notinheap +type TwoBytes [2]byte + +// EightBytes is a [8]byte which is always allocated on stack. +// +//go:notinheap +type EightBytes [8]byte