remove PacketPaddingContainer abstraction

This commit is contained in:
Shelikhoo 2025-02-13 14:01:04 +00:00
parent 955cbc847a
commit 1bc310c2e9
No known key found for this signature in database
GPG key ID: 4C9764E9FE80A3DC
6 changed files with 42 additions and 62 deletions

View file

@ -344,8 +344,7 @@ func newSession(snowflakes SnowflakeCollector) (net.PacketConn, *smux.Session, e
log.Println("---- Handler: snowflake assigned ----") log.Println("---- Handler: snowflake assigned ----")
packetConnWrapper := newPacketConnWrapper(dummyAddr{}, dummyAddr{}, packetConnWrapper := newPacketConnWrapper(dummyAddr{}, dummyAddr{},
packetpadding.NewPaddableConnection(conn, packetpadding.NewPaddableConnection(conn))
packetpadding.New()))
return packetConnWrapper, nil return packetConnWrapper, nil
} }

View file

@ -13,21 +13,19 @@ type PaddableConnection interface {
ReadWriteCloserPreservesBoundary ReadWriteCloserPreservesBoundary
} }
func NewPaddableConnection(rwc ReadWriteCloserPreservesBoundary, padding PacketPaddingContainer) PaddableConnection { func NewPaddableConnection(rwc ReadWriteCloserPreservesBoundary) PaddableConnection {
return &paddableConnection{ return &paddableConnection{
ReadWriteCloserPreservesBoundary: rwc, ReadWriteCloserPreservesBoundary: rwc,
padding: padding,
} }
} }
type paddableConnection struct { type paddableConnection struct {
ReadWriteCloserPreservesBoundary ReadWriteCloserPreservesBoundary
padding PacketPaddingContainer
} }
func (c *paddableConnection) Write(p []byte) (n int, err error) { func (c *paddableConnection) Write(p []byte) (n int, err error) {
dataLen := len(p) dataLen := len(p)
if _, err = c.ReadWriteCloserPreservesBoundary.Write(c.padding.Pack(p, 0)); err != nil { if _, err = c.ReadWriteCloserPreservesBoundary.Write(Pack(p, 0)); err != nil {
return 0, err return 0, err
} }
return dataLen, nil return dataLen, nil
@ -38,7 +36,7 @@ func (c *paddableConnection) Read(p []byte) (n int, err error) {
return 0, err return 0, err
} }
payload, _ := c.padding.Unpack(p[:n]) payload, _ := Unpack(p[:n])
if payload != nil { if payload != nil {
copy(p, payload) copy(p, payload)
} }

View file

@ -1,22 +1,36 @@
// Package packetpadding is an package that defines methods to pad packets
// with a given number of bytes, and to unpack the padding from a padded packet.
// The packet format is as follows if the desired output length is greater than
// 2 bytes:
// | data | padding | data length |
// The data length is a 16-bit big-endian integer that represents the length of
// the data in bytes.
// If the desired output length is 2 bytes or less, the packet format is as
// follows:
// | padding |
// No payload will be included in the packet.
package packetpadding package packetpadding
import "encoding/binary" import "encoding/binary"
func New() PacketPaddingContainer { // Pack pads the given data with the given number of bytes, and appends the
return packetPaddingContainer{} // length of the data to the end of the data. The returned byte slice
} // contains the padded data.
// This generates a packet with a length of
type packetPaddingContainer struct { // len(data_OWNERSHIP_RELINQUISHED) + padding + 2
} // @param data_OWNERSHIP_RELINQUISHED - The payload, this reference is consumed and should not be used after this call.
// @param padding - The number of padding bytes to add to the data.
func (c packetPaddingContainer) Pack(data_OWNERSHIP_RELINQUISHED []byte, paddingLength int) []byte { func Pack(data_OWNERSHIP_RELINQUISHED []byte, paddingLength int) []byte {
data := append(data_OWNERSHIP_RELINQUISHED, make([]byte, paddingLength)...) data := append(data_OWNERSHIP_RELINQUISHED, make([]byte, paddingLength)...)
dataLength := len(data_OWNERSHIP_RELINQUISHED) dataLength := len(data_OWNERSHIP_RELINQUISHED)
data = binary.BigEndian.AppendUint16(data, uint16(dataLength)) data = binary.BigEndian.AppendUint16(data, uint16(dataLength))
return data return data
} }
func (c packetPaddingContainer) Pad(paddingLength int) []byte { // Pad returns a padding packet of padding length.
// If the padding length is less than 0, nil is returned.
// @param padding - The number of padding bytes to add to the data.
func Pad(paddingLength int) []byte {
if assertPaddingLengthIsNotNegative := paddingLength < 0; assertPaddingLengthIsNotNegative { if assertPaddingLengthIsNotNegative := paddingLength < 0; assertPaddingLengthIsNotNegative {
return nil return nil
} }
@ -33,7 +47,11 @@ func (c packetPaddingContainer) Pad(paddingLength int) []byte {
} }
func (c packetPaddingContainer) Unpack(wrappedData_OWNERSHIP_RELINQUISHED []byte) ([]byte, int) { // Unpack extracts the data and padding from the given padded data. It
// returns the data and the number of padding bytes.
// the data may be nil.
// @param wrappedData_OWNERSHIP_RELINQUISHED - The packet, this reference is consumed and should not be used after this call.
func Unpack(wrappedData_OWNERSHIP_RELINQUISHED []byte) ([]byte, int) {
dataLength := len(wrappedData_OWNERSHIP_RELINQUISHED) dataLength := len(wrappedData_OWNERSHIP_RELINQUISHED)
if dataLength < 2 { if dataLength < 2 {
return nil, dataLength return nil, dataLength

View file

@ -1,34 +0,0 @@
package packetpadding
// PacketPaddingContainer is an interface that defines methods to pad packets
// with a given number of bytes, and to unpack the padding from a padded packet.
// The packet format is as follows if the desired output length is greater than
// 2 bytes:
// | data | padding | data length |
// The data length is a 16-bit big-endian integer that represents the length of
// the data in bytes.
// If the desired output length is 2 bytes or less, the packet format is as
// follows:
// | padding |
// No payload will be included in the packet.
type PacketPaddingContainer interface {
// Pack pads the given data with the given number of bytes, and appends the
// length of the data to the end of the data. The returned byte slice
// contains the padded data.
// This generates a packet with a length of
// len(data_OWNERSHIP_RELINQUISHED) + padding + 2
// @param data_OWNERSHIP_RELINQUISHED - The payload, this reference is consumed and should not be used after this call.
// @param padding - The number of padding bytes to add to the data.
Pack(data_OWNERSHIP_RELINQUISHED []byte, paddingLength int) []byte
// Unpack extracts the data and padding from the given padded data. It
// returns the data and the number of padding bytes.
// the data may be nil.
// @param wrappedData_OWNERSHIP_RELINQUISHED - The packet, this reference is consumed and should not be used after this call.
Unpack(wrappedData_OWNERSHIP_RELINQUISHED []byte) ([]byte, int)
// Pad returns a padding packet of padding length.
// If the padding length is less than 0, nil is returned.
// @param padding - The number of padding bytes to add to the data.
Pad(paddingLength int) []byte
}

View file

@ -10,12 +10,11 @@ import (
func TestPacketPaddingContainer(t *testing.T) { func TestPacketPaddingContainer(t *testing.T) {
Convey("Given a PacketPaddingContainer", t, func() { Convey("Given a PacketPaddingContainer", t, func() {
container := packetpadding.New()
Convey("When packing data with padding", func() { Convey("When packing data with padding", func() {
data := []byte("testdata") data := []byte("testdata")
paddingLength := 4 paddingLength := 4
packedData := container.Pack(data, paddingLength) packedData := packetpadding.Pack(data, paddingLength)
Convey("The packed data should have the correct length", func() { Convey("The packed data should have the correct length", func() {
expectedLength := len(data) + paddingLength + 2 expectedLength := len(data) + paddingLength + 2
@ -23,7 +22,7 @@ func TestPacketPaddingContainer(t *testing.T) {
}) })
Convey("When unpacking the packed data", func() { Convey("When unpacking the packed data", func() {
unpackedData, unpackedPaddingLength := container.Unpack(packedData) unpackedData, unpackedPaddingLength := packetpadding.Unpack(packedData)
Convey("The unpacked data should match the original data", func() { Convey("The unpacked data should match the original data", func() {
So(string(unpackedData), ShouldEqual, string(data)) So(string(unpackedData), ShouldEqual, string(data))
@ -38,7 +37,7 @@ func TestPacketPaddingContainer(t *testing.T) {
Convey("When packing empty data with padding", func() { Convey("When packing empty data with padding", func() {
data := []byte("") data := []byte("")
paddingLength := 4 paddingLength := 4
packedData := container.Pack(data, paddingLength) packedData := packetpadding.Pack(data, paddingLength)
Convey("The packed data should have the correct length", func() { Convey("The packed data should have the correct length", func() {
expectedLength := len(data) + paddingLength + 2 expectedLength := len(data) + paddingLength + 2
@ -46,7 +45,7 @@ func TestPacketPaddingContainer(t *testing.T) {
}) })
Convey("When unpacking the packed data", func() { Convey("When unpacking the packed data", func() {
unpackedData, unpackedPaddingLength := container.Unpack(packedData) unpackedData, unpackedPaddingLength := packetpadding.Unpack(packedData)
Convey("The unpacked data should match the original data", func() { Convey("The unpacked data should match the original data", func() {
So(string(unpackedData), ShouldEqual, string(data)) So(string(unpackedData), ShouldEqual, string(data))
@ -61,7 +60,7 @@ func TestPacketPaddingContainer(t *testing.T) {
Convey("When packing data with zero padding", func() { Convey("When packing data with zero padding", func() {
data := []byte("testdata") data := []byte("testdata")
paddingLength := 0 paddingLength := 0
packedData := container.Pack(data, paddingLength) packedData := packetpadding.Pack(data, paddingLength)
Convey("The packed data should have the correct length", func() { Convey("The packed data should have the correct length", func() {
expectedLength := len(data) + paddingLength + 2 expectedLength := len(data) + paddingLength + 2
@ -69,7 +68,7 @@ func TestPacketPaddingContainer(t *testing.T) {
}) })
Convey("When unpacking the packed data", func() { Convey("When unpacking the packed data", func() {
unpackedData, unpackedPaddingLength := container.Unpack(packedData) unpackedData, unpackedPaddingLength := packetpadding.Unpack(packedData)
Convey("The unpacked data should match the original data", func() { Convey("The unpacked data should match the original data", func() {
So(string(unpackedData), ShouldEqual, string(data)) So(string(unpackedData), ShouldEqual, string(data))
@ -84,7 +83,7 @@ func TestPacketPaddingContainer(t *testing.T) {
Convey("When padding data", func() { Convey("When padding data", func() {
Convey("With a positive padding length", func() { Convey("With a positive padding length", func() {
padLength := 3 padLength := 3
padData := container.Pad(padLength) padData := packetpadding.Pad(padLength)
Convey("The padded data should have the correct length", func() { Convey("The padded data should have the correct length", func() {
So(len(padData), ShouldEqual, padLength) So(len(padData), ShouldEqual, padLength)
@ -93,7 +92,7 @@ func TestPacketPaddingContainer(t *testing.T) {
Convey("With a zero padding length", func() { Convey("With a zero padding length", func() {
padLength := 0 padLength := 0
padData := container.Pad(padLength) padData := packetpadding.Pad(padLength)
Convey("The padded data should be empty", func() { Convey("The padded data should be empty", func() {
So(len(padData), ShouldEqual, 0) So(len(padData), ShouldEqual, 0)
@ -102,7 +101,7 @@ func TestPacketPaddingContainer(t *testing.T) {
Convey("With a negative padding length", func() { Convey("With a negative padding length", func() {
padLength := -1 padLength := -1
padData := container.Pad(padLength) padData := packetpadding.Pad(padLength)
Convey("The padded data should be nil", func() { Convey("The padded data should be nil", func() {
So(padData, ShouldBeNil) So(padData, ShouldBeNil)

View file

@ -143,7 +143,7 @@ func (handler *httpHandler) turboTunnelUDPLikeMode(conn *websocketconn.Conn, add
wg.Add(2) wg.Add(2)
done := make(chan struct{}) done := make(chan struct{})
connPaddable := packetpadding.NewPaddableConnection(conn, packetpadding.New()) connPaddable := packetpadding.NewPaddableConnection(conn)
// The remainder of the WebSocket stream consists of packets, one packet // The remainder of the WebSocket stream consists of packets, one packet
// per WebSocket message. We read them one by one and feed them into the // per WebSocket message. We read them one by one and feed them into the