mirror of
https://github.com/soypat/lneto.git
synced 2026-09-10 16:49:37 +00:00
xnet: keep working on TCPExchange test
This commit is contained in:
+105
-48
@@ -1,6 +1,7 @@
|
|||||||
package xnet
|
package xnet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
synack = tcp.FlagSYN | tcp.FlagACK
|
synack = tcp.FlagSYN | tcp.FlagACK
|
||||||
|
pshack = tcp.FlagPSH | tcp.FlagACK
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestABC(t *testing.T) {
|
func TestABC(t *testing.T) {
|
||||||
@@ -76,62 +78,117 @@ func TestABC(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var expected = []struct {
|
tst := tester{
|
||||||
fromClient bool
|
t: t, buf: make([]byte, MTU),
|
||||||
flags tcp.Flags
|
}
|
||||||
}{
|
const flagNoData = tcp.Flags(0)
|
||||||
|
noMoreData := []tcpExpectExchange{{SourceIdx: 0, WantFlags: flagNoData}, {SourceIdx: 1, WantFlags: flagNoData}}
|
||||||
|
expected := []tcpExpectExchange{
|
||||||
{
|
{
|
||||||
fromClient: true,
|
SourceIdx: 0,
|
||||||
flags: tcp.FlagSYN,
|
WantFlags: tcp.FlagSYN,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fromClient: false,
|
SourceIdx: 1,
|
||||||
flags: synack,
|
WantFlags: synack,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fromClient: true,
|
SourceIdx: 0,
|
||||||
flags: tcp.FlagACK,
|
WantFlags: tcp.FlagACK,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
var cap pcap.PacketBreakdown
|
expected = append(expected, noMoreData...) // Ensure no data exchanged after expected.
|
||||||
var frms []pcap.Frame
|
for _, wants := range expected {
|
||||||
var buf [MTU]byte
|
tst.TCPExchange(wants, &client, &sv)
|
||||||
for _, action := range expected {
|
}
|
||||||
var n int
|
sendData := []byte("hello")
|
||||||
switch action.fromClient {
|
_, err = clconn.Write(sendData)
|
||||||
case true:
|
if err != nil {
|
||||||
n, err = client.Encapsulate(buf[:], 0)
|
t.Fatal(err)
|
||||||
case false:
|
}
|
||||||
n, err = sv.Encapsulate(buf[:], 0)
|
expected = []tcpExpectExchange{
|
||||||
}
|
{
|
||||||
if err != nil {
|
SourceIdx: 0,
|
||||||
t.Fatal(err)
|
WantFlags: pshack,
|
||||||
} else if n == 0 {
|
WantData: sendData,
|
||||||
t.Error("zero bits sent")
|
},
|
||||||
}
|
{
|
||||||
frms, err = cap.CaptureEthernet(frms[:0], buf[:n], 0)
|
SourceIdx: 1,
|
||||||
if err != nil {
|
WantFlags: tcp.FlagACK,
|
||||||
t.Fatal(err)
|
},
|
||||||
}
|
}
|
||||||
tfrm := getProtoFrame(frms, lneto.IPProtoTCP)
|
expected = append(expected, noMoreData...) // Ensure no data exchanged after expected.
|
||||||
if tfrm == nil {
|
for _, wants := range expected {
|
||||||
t.Fatal("where's the TCP?")
|
tst.TCPExchange(wants, &client, &sv)
|
||||||
}
|
}
|
||||||
fidx, _ := tfrm.FieldByClass(pcap.FieldClassFlags)
|
}
|
||||||
flags, _ := tfrm.FieldAsUint(fidx, buf[:n])
|
|
||||||
tflags := tcp.Flags(flags)
|
type tester struct {
|
||||||
if tflags != action.flags {
|
t *testing.T
|
||||||
t.Errorf("expected flags %s, got %s", action.flags.String(), tflags.String())
|
cap pcap.PacketBreakdown
|
||||||
}
|
frmbuf []pcap.Frame
|
||||||
switch action.fromClient {
|
buf []byte
|
||||||
case true:
|
}
|
||||||
err = sv.Demux(buf[:], 0)
|
|
||||||
case false:
|
type tcpExpectExchange struct {
|
||||||
err = client.Demux(buf[:], 0)
|
SourceIdx int
|
||||||
}
|
WantFlags tcp.Flags
|
||||||
if err != nil {
|
WantData []byte
|
||||||
t.Fatal(err)
|
}
|
||||||
|
|
||||||
|
func (tst *tester) TCPExchange(expect tcpExpectExchange, stack1, stack2 *StackAsync) {
|
||||||
|
t := tst.t
|
||||||
|
buf := tst.buf
|
||||||
|
nodata := expect.WantFlags == 0
|
||||||
|
var n int
|
||||||
|
var err error
|
||||||
|
switch expect.SourceIdx {
|
||||||
|
case 0:
|
||||||
|
n, err = stack1.Encapsulate(buf[:], 0)
|
||||||
|
case 1:
|
||||||
|
n, err = stack2.Encapsulate(buf[:], 0)
|
||||||
|
default:
|
||||||
|
panic("OOB")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if n == 0 {
|
||||||
|
if nodata {
|
||||||
|
return // No data sent and no data expected.
|
||||||
}
|
}
|
||||||
|
t.Error("zero bits sent")
|
||||||
|
}
|
||||||
|
tst.frmbuf, err = tst.cap.CaptureEthernet(tst.frmbuf[:0], buf[:n], 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
tfrm := getProtoFrame(tst.frmbuf, lneto.IPProtoTCP)
|
||||||
|
if tfrm == nil {
|
||||||
|
t.Fatal("where's the TCP?")
|
||||||
|
}
|
||||||
|
fidx, _ := tfrm.FieldByClass(pcap.FieldClassFlags)
|
||||||
|
flags, _ := tfrm.FieldAsUint(fidx, buf[:n])
|
||||||
|
tflags := tcp.Flags(flags)
|
||||||
|
var payload []byte
|
||||||
|
fidx, _ = tfrm.FieldByClass(pcap.FieldClassPayload)
|
||||||
|
if fidx > 0 {
|
||||||
|
fieldPayload := tfrm.Fields[fidx]
|
||||||
|
payload = buf[fieldPayload.FrameBitOffset*8:]
|
||||||
|
}
|
||||||
|
if !bytes.Equal(payload, expect.WantData) {
|
||||||
|
t.Errorf("mismatched data sent, \nwant=%q\ngot=%q\n", expect.WantData, payload)
|
||||||
|
}
|
||||||
|
if tflags != expect.WantFlags {
|
||||||
|
t.Errorf("expected flags %s, got %s", expect.WantFlags.String(), tflags.String())
|
||||||
|
}
|
||||||
|
switch expect.SourceIdx {
|
||||||
|
case 0:
|
||||||
|
err = stack2.Demux(buf[:], 0)
|
||||||
|
case 1:
|
||||||
|
err = stack1.Demux(buf[:], 0)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user