From 59ff44025c02dd188eef68ad5f722132801b717e Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sun, 10 Sep 2017 05:20:00 +0200 Subject: new and greatly improved packet handling --- satp/packet.go | 165 +++++++++++-------- satp/packet_test.go | 451 ++++++++++++++++++++++++++-------------------------- 2 files changed, 327 insertions(+), 289 deletions(-) (limited to 'satp') diff --git a/satp/packet.go b/satp/packet.go index 7e638fa..22cf4ba 100644 --- a/satp/packet.go +++ b/satp/packet.go @@ -31,11 +31,12 @@ package satp import ( - "bytes" "encoding/binary" "errors" + "io" ) +// // 0 1 2 3 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -53,96 +54,130 @@ import ( // | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | // | | // +- Encrypted Portion Authenticated Portion ---+ +// + +const ( + PACKET_BUFFER_SIZE = 16384 +) + +var ( + ErrTooShort = errors.New("packet is too short") +) type PlainPacket struct { - Type uint16 - Payload []byte + buffer [PACKET_BUFFER_SIZE]byte + header []byte + payload []byte } -func NewPlainPacket(PayloadType uint16) (pp *PlainPacket) { +func NewPlainPacket() (pp *PlainPacket) { pp = &PlainPacket{} - pp.Type = PayloadType + pp.header = pp.buffer[:2:2] + pp.payload = pp.buffer[2:2] return } -func (pp *PlainPacket) MarshalBinary() (data []byte, err error) { - buf := &bytes.Buffer{} - if err = binary.Write(buf, binary.BigEndian, pp.Type); err != nil { - return - } - buf.Write(pp.Payload) // returned error is always nil - return buf.Bytes(), nil +func (pp *PlainPacket) SetPayloadType(payloadType uint16) { + binary.BigEndian.PutUint16(pp.header, payloadType) + return } -func (pp *PlainPacket) UnmarshalBinary(data []byte) (err error) { - buf := bytes.NewReader(data) - if err = binary.Read(buf, binary.BigEndian, &(pp.Type)); err != nil { - return - } - if buf.Len() > 0 { - pp.Payload = make([]byte, buf.Len()) - buf.Read(pp.Payload) +func (pp *PlainPacket) GetPayloadType() (payloadType uint16) { + return binary.BigEndian.Uint16(pp.header) +} + +func (pp *PlainPacket) getPacket() (data []byte) { + return pp.buffer[:len(pp.header)+len(pp.payload)] +} + +func (pp *PlainPacket) ReadFrom(r io.Reader) (int64, error) { + n, err := r.Read(pp.payload[:cap(pp.payload)]) + if err != nil && err != io.EOF { + return 0, err } - return + pp.payload = pp.payload[:n] + return int64(n), nil +} + +func (pp *PlainPacket) WriteTo(w io.Writer) (int64, error) { + n, err := w.Write(pp.payload) + return int64(n), err } type EncryptedPacket struct { - SequenceNumber uint32 - SenderID uint16 - Mux uint16 - Payload []byte - AuthTag []byte + buffer [PACKET_BUFFER_SIZE]byte + header []byte + payload []byte + authTag []byte } -func NewEncryptedPacket(AuthTagLength uint) (ep *EncryptedPacket) { +func NewEncryptedPacket() (ep *EncryptedPacket) { ep = &EncryptedPacket{} - if AuthTagLength > 0 { - ep.AuthTag = make([]byte, AuthTagLength) - } + ep.header = ep.buffer[:8:8] + ep.payload = ep.buffer[8:] + ep.authTag = nil return } -func (ep *EncryptedPacket) MarshalBinary() (data []byte, err error) { - buf := &bytes.Buffer{} - if err = binary.Write(buf, binary.BigEndian, ep.SequenceNumber); err != nil { - return - } - if err = binary.Write(buf, binary.BigEndian, ep.SenderID); err != nil { - return - } - if err = binary.Write(buf, binary.BigEndian, ep.Mux); err != nil { - return +func (ep *EncryptedPacket) SetAuthTagLength(length int) error { + total := len(ep.payload) + len(ep.authTag) + if length <= 0 { + ep.payload = ep.payload[:total] + ep.authTag = nil } - if len(ep.Payload) >= 2 { // Payload must at least have a payload type which is a uint16 -> 2 bytes - buf.Write(ep.Payload) // returned error is always nil - } else { - return nil, errors.New("Unable to marshal packet: payload is empty/too short") + if length > total { + return ErrTooShort } + ep.payload = ep.payload[:total-length] + ep.authTag = ep.buffer[len(ep.header)+len(ep.payload) : total] + return nil +} - if len(ep.AuthTag) > 0 { - buf.Write(ep.AuthTag) // returned error is always nil - } - return buf.Bytes(), nil +func (ep *EncryptedPacket) GetAuthTagLength() int { + return len(ep.authTag) } -func (ep *EncryptedPacket) UnmarshalBinary(data []byte) (err error) { - buf := bytes.NewReader(data) - if err = binary.Read(buf, binary.BigEndian, &(ep.SequenceNumber)); err != nil { - return - } - if err = binary.Read(buf, binary.BigEndian, &(ep.SenderID)); err != nil { - return - } - if err = binary.Read(buf, binary.BigEndian, &(ep.Mux)); err != nil { - return - } +func (ep *EncryptedPacket) SetSequenceNumber(sequenceNumber uint32) { + binary.BigEndian.PutUint32(ep.header[:4], sequenceNumber) + return +} - if (buf.Len() - len(ep.AuthTag)) < 2 { // 2 bytes payload type + length of AuthTag must be left on buffer - return errors.New("Unable to unmarshal packet: too short") - } +func (ep *EncryptedPacket) GetSequenceNumber() (sequenceNumber uint32) { + return binary.BigEndian.Uint32(ep.header[:4]) +} + +func (ep *EncryptedPacket) SetSenderID(senderID uint16) { + binary.BigEndian.PutUint16(ep.header[4:6], senderID) + return +} - ep.Payload = make([]byte, buf.Len()-len(ep.AuthTag)) - buf.Read(ep.Payload) - buf.Read(ep.AuthTag) +func (ep *EncryptedPacket) GetSenderID() (senderID uint16) { + return binary.BigEndian.Uint16(ep.header[4:6]) +} + +func (ep *EncryptedPacket) SetMux(mux uint16) { + binary.BigEndian.PutUint16(ep.header[6:8], mux) return } + +func (ep *EncryptedPacket) GetMux() (mux uint16) { + return binary.BigEndian.Uint16(ep.header[6:8]) +} + +func (ep *EncryptedPacket) ReadFrom(r io.Reader) (int64, error) { + n, err := r.Read(ep.buffer[:]) + if err != nil && err != io.EOF { + return 0, err + } + if n < len(ep.header)+2+len(ep.authTag) { + return 0, ErrTooShort + } + ep.payload = ep.payload[:n-len(ep.header)] + err = ep.SetAuthTagLength(len(ep.authTag)) + return int64(n), err +} + +func (ep *EncryptedPacket) WriteTo(w io.Writer) (int64, error) { + n, err := w.Write(ep.buffer[:len(ep.header)+len(ep.payload)+len(ep.authTag)]) + return int64(n), err +} diff --git a/satp/packet_test.go b/satp/packet_test.go index 0aa3df4..a69bb10 100644 --- a/satp/packet_test.go +++ b/satp/packet_test.go @@ -33,7 +33,8 @@ package satp import ( "bytes" "math/rand" - "reflect" + // "reflect" + "io/ioutil" "testing" ) @@ -42,8 +43,10 @@ const ( ) var ( - IPv4 = uint16(0x0800) - IPv4Ping = []byte{ + IPv4Packet *PlainPacket + IPv4Type = uint16(0x0800) + IPv4Ping *PlainPacket + IPv4PingData = [...]byte{ 0x45, 0x00, 0x00, 0x54, 0xB7, 0xCC, 0x40, 0x00, 0x40, 0x01, 0xAD, 0x73, 0xC0, 0xA8, 0x2A, 0x17, 0xC0, 0xA8, 0x2A, 0x01, 0x08, 0x00, 0xB4, 0x04, 0x3D, 0xE2, 0x00, 0x01, 0xE6, 0x00, 0xB1, 0x59, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xEA, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, @@ -51,8 +54,10 @@ var ( 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37} - IPv6 = uint16(0x86DD) - IPv6Ping = []byte{ + IPv6Packet *PlainPacket + IPv6Type = uint16(0x86DD) + IPv6Ping *PlainPacket + IPv6PingData = [...]byte{ 0x60, 0x0E, 0x9B, 0x1F, 0x00, 0x40, 0x3A, 0x40, 0x2A, 0x02, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2A, 0x02, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x80, 0x00, 0xE6, 0x21, 0x46, 0x22, 0x00, 0x01, @@ -61,235 +66,234 @@ var ( 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37} - Ethernet = uint16(0x6558) - ARPRequest = []byte{ + EthernetFrame *PlainPacket + EthernetType = uint16(0x6558) + ARPRequest *PlainPacket + ARPRequestData = [...]byte{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC6, 0x5A, 0xD4, 0xC7, 0x23, 0x43, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xC6, 0x5A, 0xD4, 0xC7, 0x23, 0x43, 0xC0, 0xA8, 0x2A, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, 0x2A, 0x01} ) -func TestPlainPacketMarshal(t *testing.T) { - testvectors := []struct { - packet PlainPacket - valid bool - expected []byte - }{ - {PlainPacket{}, true, []byte{0x0, 0x0}}, - {*NewPlainPacket(IPv4), true, []byte{0x8, 0x0}}, - {*NewPlainPacket(IPv6), true, []byte{0x86, 0xDD}}, - {PlainPacket{Type: Ethernet, Payload: []byte{0x0, 0x0, 0x0}}, true, []byte{0x65, 0x58, 0x0, 0x0, 0x0}}, - {PlainPacket{Type: 0x0800, Payload: IPv4Ping}, true, append([]byte{0x8, 0x0}, IPv4Ping...)}, - {PlainPacket{Type: 0x86DD, Payload: IPv6Ping}, true, append([]byte{0x86, 0xDD}, IPv6Ping...)}, - {PlainPacket{Type: 0x6558, Payload: ARPRequest}, true, append([]byte{0x65, 0x58}, ARPRequest...)}, - } +func init() { + IPv4Packet = NewPlainPacket() + IPv4Packet.SetPayloadType(IPv4Type) - for _, vector := range testvectors { - result, err := vector.packet.MarshalBinary() - if vector.valid { - if err != nil { - t.Fatal("unexpected error:", err) - } - if bytes.Compare(vector.expected, result) != 0 { - t.Fatalf("resulting packet is invalid is: '%v', should be '%v'", result, vector.expected) - } - } else { - if err == nil { - t.Fatalf("marshalling '%+v' should give an error", vector.packet) - } - } - } -} + IPv4Ping = NewPlainPacket() + IPv4Ping.SetPayloadType(IPv4Type) -func TestPlainPacketUnmarshal(t *testing.T) { - testvectors := []struct { - data []byte - valid bool - expected PlainPacket - }{ - {[]byte{}, false, PlainPacket{}}, - {[]byte{0x0}, false, PlainPacket{}}, - {[]byte{0x0, 0x0}, true, PlainPacket{}}, - {[]byte{0x8, 0x0}, true, *NewPlainPacket(IPv4)}, - {[]byte{0x86, 0xDD}, true, *NewPlainPacket(IPv6)}, - {[]byte{0x65, 0x58, 0x0, 0x0, 0x0}, true, PlainPacket{Type: Ethernet, Payload: []byte{0x0, 0x0, 0x0}}}, - {append([]byte{0x8, 0x0}, IPv4Ping...), true, PlainPacket{Type: 0x0800, Payload: IPv4Ping}}, - {append([]byte{0x86, 0xDD}, IPv6Ping...), true, PlainPacket{Type: 0x86DD, Payload: IPv6Ping}}, - {append([]byte{0x65, 0x58}, ARPRequest...), true, PlainPacket{Type: 0x6558, Payload: ARPRequest}}, - } + IPv6Packet = NewPlainPacket() + IPv6Packet.SetPayloadType(IPv6Type) - for _, vector := range testvectors { - var result PlainPacket - err := result.UnmarshalBinary(vector.data) - if vector.valid { - if err != nil { - t.Fatal("unexpected error:", err) - } - if !reflect.DeepEqual(vector.expected, result) { - t.Fatalf("unmarshalled packet is wrong: is '%+v', should be '%+v'", result, vector.expected) - } - } else { - if err == nil { - t.Fatalf("unmarshalling '%+v' should give an error", vector.data) - } - } - } -} + IPv6Ping = NewPlainPacket() + IPv6Ping.SetPayloadType(IPv6Type) -func generateRandomTestDataPlainPacket() (pp *PlainPacket) { - payloadlen := uint(rand.Int31n(2000)) + EthernetFrame = NewPlainPacket() + EthernetFrame.SetPayloadType(EthernetType) - pp = NewPlainPacket(uint16(rand.Uint32())) - pp.Payload = make([]byte, payloadlen) - rand.Read(pp.Payload) - return + ARPRequest = NewPlainPacket() + ARPRequest.SetPayloadType(EthernetType) } -func TestPlainPacketMarshalUnmarshal(t *testing.T) { - for i := 0; i < NUM_RANDOM_DATASETS; i++ { - in := generateRandomTestDataPlainPacket() - marshalled, err := in.MarshalBinary() - if err != nil { - t.Fatal("unexpected error:", err) - } - out := &PlainPacket{} - if err = out.UnmarshalBinary(marshalled); err != nil { - t.Fatal("unexpected error:", err) +func TestPlainPacketPayloadType(t *testing.T) { + testvectors := []uint16{0, IPv4Type, IPv6Type, EthernetType, 0xAA55, 0xF00F} + + for _, vector := range testvectors { + pkt := NewPlainPacket() + if vector > 0 { + pkt.SetPayloadType(vector) } - if !reflect.DeepEqual(in, out) { - t.Fatalf("unmarshalled packet is wrong: is '%+v', should be '%+v'", out, in) + result := pkt.getPacket() + expected := []byte{byte(vector >> 8), byte(vector)} + if bytes.Compare(result, expected) != 0 { + t.Fatalf("resulting packet is invalid is: '%v', should be '%v'", result, expected) } - } -} -func TestEncryptedPacketMarshal(t *testing.T) { - testvectors := []struct { - packet EncryptedPacket - valid bool - expected []byte - }{ - {EncryptedPacket{}, false, []byte{}}, - {EncryptedPacket{Payload: []byte{0x0}}, false, []byte{}}, - {EncryptedPacket{Payload: []byte{0x8}}, false, []byte{}}, - {EncryptedPacket{Payload: []byte{0x0, 0x0}}, true, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, - {EncryptedPacket{Payload: []byte{0x42, 0x23}}, true, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x23}}, - {EncryptedPacket{Payload: []byte{0x17, 0x4, 0x0}}, true, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0x4, 0x0}}, - {*NewEncryptedPacket(3), false, []byte{}}, - {EncryptedPacket{Payload: []byte{0x00, 0x56, 0xa5}, AuthTag: make([]byte, 3)}, true, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x56, 0xa5, 0x0, 0x0, 0x0}}, - } - - for _, vector := range testvectors { - result, err := vector.packet.MarshalBinary() - if vector.valid { - if err != nil { - t.Fatal("unexpected error:", err) - } - if bytes.Compare(vector.expected, result) != 0 { - t.Fatalf("resulting packet is invalid is: '%v', should be '%v'", result, vector.expected) - } - } else { - if err == nil { - t.Fatalf("marshalling '%+v' should give an error", vector.packet) - } + payloadType := pkt.GetPayloadType() + if vector != payloadType { + t.Fatalf("resulting payload type is invalid is: '%v', should be '%v'", payloadType, vector) } } } -func TestEncryptedPacketUnmarshal(t *testing.T) { - testvectors := []struct { - data []byte - valid bool - authTagLen uint - expected EncryptedPacket - }{ - {[]byte{}, false, 0, EncryptedPacket{}}, - {[]byte{0x0, 0x0}, false, 0, EncryptedPacket{}}, - {[]byte{0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, - {[]byte{0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, - {[]byte{0x0, 0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, - {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, - {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, - {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, - {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, - {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, true, 0, EncryptedPacket{Payload: []byte{0x0, 0x0}}}, - {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, false, 1, EncryptedPacket{Payload: []byte{0x0, 0x0}}}, - {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, true, 1, EncryptedPacket{Payload: []byte{0x0, 0x0}, AuthTag: []byte{0x0}}}, - {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, true, 0, EncryptedPacket{Payload: []byte{0x0, 0x0, 0x0}}}, - {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, true, 3, EncryptedPacket{Payload: []byte{0x0, 0x0}, AuthTag: []byte{0x0, 0x0, 0x0}}}, - } +func TestPlainPacketReadFrom(t *testing.T) { + // TODO: implement this +} - for _, vector := range testvectors { - result := *NewEncryptedPacket(vector.authTagLen) - err := result.UnmarshalBinary(vector.data) - if vector.valid { - if err != nil { - t.Fatal("unexpected error:", err) - } - if !reflect.DeepEqual(vector.expected, result) { - t.Fatalf("unmarshalled packet is wrong: is '%+v', should be '%+v'", result, vector.expected) - } - } else { - if err == nil { - t.Fatalf("unmarshalling '%+v' should give an error", vector.data) - } - } - } +func TestPlainPacketWriteTo(t *testing.T) { + // TODO: implement this } -func generateRandomTestDataEncryptedPacket() (ep *EncryptedPacket) { - authtaglen := uint(rand.Int31n(32)) - payloadlen := uint(2 + rand.Int31n(2000)) +func generateRandomTestDataPlainPacket() (payloadType uint16, payload []byte) { + payloadType = uint16(rand.Uint32()) - ep = NewEncryptedPacket(authtaglen) - ep.SequenceNumber = rand.Uint32() - ep.SenderID = uint16(rand.Uint32()) - ep.Mux = uint16(rand.Uint32()) - ep.Payload = make([]byte, payloadlen) - rand.Read(ep.Payload) + packetlen := uint(2 + rand.Int31n(PACKET_BUFFER_SIZE-2)) + payload = make([]byte, packetlen) + rand.Read(payload) return } -func TestEncryptedPacketMarshalUnmarshal(t *testing.T) { +func TestPlainPacketReadWrite(t *testing.T) { for i := 0; i < NUM_RANDOM_DATASETS; i++ { - in := generateRandomTestDataEncryptedPacket() - marshalled, err := in.MarshalBinary() + pkt := NewPlainPacket() + inType, in := generateRandomTestDataPlainPacket() + + pkt.SetPayloadType(inType) + n, err := pkt.ReadFrom(bytes.NewReader(in)) if err != nil { t.Fatal("unexpected error:", err) } - out := NewEncryptedPacket(uint(len(in.AuthTag))) - if err = out.UnmarshalBinary(marshalled); err != nil { + if n != int64(len(in)) { + t.Fatalf("returned length is invalid is: %d, should be %d", n, len(in)) + } + + out := &bytes.Buffer{} + if n, err = pkt.WriteTo(out); err != nil { t.Fatal("unexpected error:", err) } - if !reflect.DeepEqual(in, out) { - t.Fatalf("unmarshalled packet is wrong: is '%+v', should be '%+v'", out, in) + if n != int64(len(in)) { + t.Fatalf("returned length is invalid is: %d, should be %d", n, len(in)) + } + + if bytes.Compare(in, out.Bytes()) != 0 { + t.Fatalf("resulting packet is invalid is: '%v', should be '%v'", out.Bytes(), in) } } } +// func TestEncryptedPacketMarshal(t *testing.T) { +// testvectors := []struct { +// packet EncryptedPacket +// valid bool +// expected []byte +// }{ +// {EncryptedPacket{}, false, []byte{}}, +// {EncryptedPacket{Payload: []byte{0x0}}, false, []byte{}}, +// {EncryptedPacket{Payload: []byte{0x8}}, false, []byte{}}, +// {EncryptedPacket{Payload: []byte{0x0, 0x0}}, true, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, +// {EncryptedPacket{Payload: []byte{0x42, 0x23}}, true, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x23}}, +// {EncryptedPacket{Payload: []byte{0x17, 0x4, 0x0}}, true, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0x4, 0x0}}, +// {*NewEncryptedPacket(3), false, []byte{}}, +// {EncryptedPacket{Payload: []byte{0x00, 0x56, 0xa5}, AuthTag: make([]byte, 3)}, true, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x56, 0xa5, 0x0, 0x0, 0x0}}, +// } + +// for _, vector := range testvectors { +// result, err := vector.packet.MarshalBinary() +// if vector.valid { +// if err != nil { +// t.Fatal("unexpected error:", err) +// } +// if bytes.Compare(vector.expected, result) != 0 { +// t.Fatalf("resulting packet is invalid is: '%v', should be '%v'", result, vector.expected) +// } +// } else { +// if err == nil { +// t.Fatalf("marshalling '%+v' should give an error", vector.packet) +// } +// } +// } +// } + +// func TestEncryptedPacketUnmarshal(t *testing.T) { +// testvectors := []struct { +// data []byte +// valid bool +// authTagLen uint +// expected EncryptedPacket +// }{ +// {[]byte{}, false, 0, EncryptedPacket{}}, +// {[]byte{0x0, 0x0}, false, 0, EncryptedPacket{}}, +// {[]byte{0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, +// {[]byte{0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, +// {[]byte{0x0, 0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, +// {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, +// {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, +// {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, +// {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, false, 0, EncryptedPacket{}}, +// {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, true, 0, EncryptedPacket{Payload: []byte{0x0, 0x0}}}, +// {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, false, 1, EncryptedPacket{Payload: []byte{0x0, 0x0}}}, +// {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, true, 1, EncryptedPacket{Payload: []byte{0x0, 0x0}, AuthTag: []byte{0x0}}}, +// {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, true, 0, EncryptedPacket{Payload: []byte{0x0, 0x0, 0x0}}}, +// {[]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, true, 3, EncryptedPacket{Payload: []byte{0x0, 0x0}, AuthTag: []byte{0x0, 0x0, 0x0}}}, +// } + +// for _, vector := range testvectors { +// result := *NewEncryptedPacket(vector.authTagLen) +// err := result.UnmarshalBinary(vector.data) +// if vector.valid { +// if err != nil { +// t.Fatal("unexpected error:", err) +// } +// if !reflect.DeepEqual(vector.expected, result) { +// t.Fatalf("unmarshalled packet is wrong: is '%+v', should be '%+v'", result, vector.expected) +// } +// } else { +// if err == nil { +// t.Fatalf("unmarshalling '%+v' should give an error", vector.data) +// } +// } +// } +// } + +// func generateRandomTestDataEncryptedPacket() (ep *EncryptedPacket) { +// authtaglen := uint(rand.Int31n(32)) +// payloadlen := uint(2 + rand.Int31n(2000)) + +// ep = NewEncryptedPacket(authtaglen) +// ep.SequenceNumber = rand.Uint32() +// ep.SenderID = uint16(rand.Uint32()) +// ep.Mux = uint16(rand.Uint32()) +// ep.Payload = make([]byte, payloadlen) +// rand.Read(ep.Payload) +// return +// } + +// func TestEncryptedPacketMarshalUnmarshal(t *testing.T) { +// for i := 0; i < NUM_RANDOM_DATASETS; i++ { +// in := generateRandomTestDataEncryptedPacket() +// marshalled, err := in.MarshalBinary() +// if err != nil { +// t.Fatal("unexpected error:", err) +// } +// out := NewEncryptedPacket(uint(len(in.AuthTag))) +// if err = out.UnmarshalBinary(marshalled); err != nil { +// t.Fatal("unexpected error:", err) +// } +// if !reflect.DeepEqual(in, out) { +// t.Fatalf("unmarshalled packet is wrong: is '%+v', should be '%+v'", out, in) +// } +// } +// } + // // Benchmarking // -func BenchmarkPlainPacketMarshal(b *testing.B) { - ins := []*PlainPacket{} +func BenchmarkPlainPacketReadFrom(b *testing.B) { + ins := []*bytes.Buffer{} for i := 0; i < NUM_RANDOM_DATASETS; i++ { - ins = append(ins, generateRandomTestDataPlainPacket()) + _, payload := generateRandomTestDataPlainPacket() + ins = append(ins, bytes.NewBuffer(payload)) } + pkt := NewPlainPacket() b.ResetTimer() for i := 0; i < b.N; i++ { in := ins[i%len(ins)] - if _, err := in.MarshalBinary(); err != nil { + in.Reset() + if _, err := pkt.ReadFrom(in); err != nil { b.Fatal("unexpected error:", err) } } } -func BenchmarkPlainPacketUnMarshal(b *testing.B) { - ins := [][]byte{} +func BenchmarkPlainPacketWriteTo(b *testing.B) { + ins := []*PlainPacket{} for i := 0; i < NUM_RANDOM_DATASETS; i++ { - in, err := generateRandomTestDataPlainPacket().MarshalBinary() - if err != nil { + _, payload := generateRandomTestDataPlainPacket() + in := NewPlainPacket() + if _, err := in.ReadFrom(bytes.NewReader(payload)); err != nil { b.Fatal("unexpected error:", err) } ins = append(ins, in) @@ -299,51 +303,50 @@ func BenchmarkPlainPacketUnMarshal(b *testing.B) { for i := 0; i < b.N; i++ { in := ins[i%len(ins)] - out := &PlainPacket{} - if err := out.UnmarshalBinary(in); err != nil { - b.Fatal("unexpected error:", err) - } - } -} - -func BenchmarkEncryptedPacketMarshal(b *testing.B) { - ins := []*EncryptedPacket{} - for i := 0; i < NUM_RANDOM_DATASETS; i++ { - ins = append(ins, generateRandomTestDataEncryptedPacket()) - } - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - in := ins[i%len(ins)] - if _, err := in.MarshalBinary(); err != nil { + if _, err := in.WriteTo(ioutil.Discard); err != nil { b.Fatal("unexpected error:", err) } } } -func BenchmarkEncryptedPacketUnMarshal(b *testing.B) { - type inType struct { - authTagLen uint - data []byte - } - ins := []inType{} - for i := 0; i < NUM_RANDOM_DATASETS; i++ { - pkt := generateRandomTestDataEncryptedPacket() - inData, err := pkt.MarshalBinary() - if err != nil { - b.Fatal("unexpected error:", err) - } - ins = append(ins, inType{uint(len(pkt.AuthTag)), inData}) - } - - b.ResetTimer() - - for i := 0; i < b.N; i++ { - in := ins[i%len(ins)] - out := NewEncryptedPacket(in.authTagLen) - if err := out.UnmarshalBinary(in.data); err != nil { - b.Fatal("unexpected error:", err) - } - } -} +// func BenchmarkEncryptedPacketMarshal(b *testing.B) { +// ins := []*EncryptedPacket{} +// for i := 0; i < NUM_RANDOM_DATASETS; i++ { +// ins = append(ins, generateRandomTestDataEncryptedPacket()) +// } + +// b.ResetTimer() + +// for i := 0; i < b.N; i++ { +// in := ins[i%len(ins)] +// if _, err := in.MarshalBinary(); err != nil { +// b.Fatal("unexpected error:", err) +// } +// } +// } + +// func BenchmarkEncryptedPacketUnMarshal(b *testing.B) { +// type inType struct { +// authTagLen uint +// data []byte +// } +// ins := []inType{} +// for i := 0; i < NUM_RANDOM_DATASETS; i++ { +// pkt := generateRandomTestDataEncryptedPacket() +// inData, err := pkt.MarshalBinary() +// if err != nil { +// b.Fatal("unexpected error:", err) +// } +// ins = append(ins, inType{uint(len(pkt.AuthTag)), inData}) +// } + +// b.ResetTimer() + +// for i := 0; i < b.N; i++ { +// in := ins[i%len(ins)] +// out := NewEncryptedPacket(in.authTagLen) +// if err := out.UnmarshalBinary(in.data); err != nil { +// b.Fatal("unexpected error:", err) +// } +// } +// } -- cgit v1.2.3