mirror of
https://github.com/soypat/lneto.git
synced 2026-09-10 08:39:30 +00:00
add xnet stack tcp handshake test
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/soypat/lneto/internal"
|
"github.com/soypat/lneto/internal"
|
||||||
"github.com/soypat/lneto/internal/ltesto"
|
"github.com/soypat/lneto/internal/ltesto"
|
||||||
"github.com/soypat/lneto/internet/pcap"
|
"github.com/soypat/lneto/internet/pcap"
|
||||||
|
"github.com/soypat/lneto/tcp"
|
||||||
"github.com/soypat/lneto/x/xnet"
|
"github.com/soypat/lneto/x/xnet"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -97,8 +98,6 @@ func run() (err error) {
|
|||||||
HardwareAddress: brHW,
|
HardwareAddress: brHW,
|
||||||
MTU: uint16(mtu),
|
MTU: uint16(mtu),
|
||||||
MaxTCPConns: 1,
|
MaxTCPConns: 1,
|
||||||
TCPBufferSizeTx: 2048,
|
|
||||||
TCPBufferSizeRx: 2048,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -199,6 +198,12 @@ func run() (err error) {
|
|||||||
return fmt.Errorf("DNS of host %q failed: %w", flagHostToResolve, err)
|
return fmt.Errorf("DNS of host %q failed: %w", flagHostToResolve, err)
|
||||||
}
|
}
|
||||||
fmt.Printf("DNS resolution of %q complete and resolved to %v\n", flagHostToResolve, addrs)
|
fmt.Printf("DNS resolution of %q complete and resolved to %v\n", flagHostToResolve, addrs)
|
||||||
|
var conn tcp.Conn
|
||||||
|
conn.Configure(tcp.ConnConfig{
|
||||||
|
RxBuf: make([]byte, mtu),
|
||||||
|
TxBuf: make([]byte, mtu),
|
||||||
|
TxPacketQueueSize: 3,
|
||||||
|
})
|
||||||
if flagHTTPGet {
|
if flagHTTPGet {
|
||||||
var hdr httpraw.Header
|
var hdr httpraw.Header
|
||||||
hdr.SetMethod("GET")
|
hdr.SetMethod("GET")
|
||||||
@@ -213,7 +218,7 @@ func run() (err error) {
|
|||||||
}
|
}
|
||||||
const tcpDebugTimeout = 60 * time.Minute
|
const tcpDebugTimeout = 60 * time.Minute
|
||||||
target := netip.AddrPortFrom(addrs[0], 80)
|
target := netip.AddrPortFrom(addrs[0], 80)
|
||||||
conn, err := rstack.DoDialTCP(uint16(softRand&0xefff)+1024, target, tcpDebugTimeout, internetRetries)
|
err = rstack.DoDialTCP(&conn, uint16(softRand&0xefff)+1024, target, tcpDebugTimeout, internetRetries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("TCP failed: %w", err)
|
return fmt.Errorf("TCP failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ func (ls *StackEthernet) SetGateway6(gw [6]byte) {
|
|||||||
ls.gwmac = gw
|
ls.gwmac = gw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ls *StackEthernet) Gateway6() (gw [6]byte) {
|
||||||
|
return ls.gwmac
|
||||||
|
}
|
||||||
|
|
||||||
func (ls *StackEthernet) SetHardwareAddr6(mac [6]byte) {
|
func (ls *StackEthernet) SetHardwareAddr6(mac [6]byte) {
|
||||||
ls.mac = mac
|
ls.mac = mac
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-6
@@ -210,26 +210,42 @@ func (s *StackAsync) SetHardwareAddress(hw [6]byte) error {
|
|||||||
return s.resetARP()
|
return s.resetARP()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StackAsync) HardwareAddress() (hw [6]byte) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
return s.link.HardwareAddr6()
|
||||||
|
}
|
||||||
|
|
||||||
func (s *StackAsync) SetGateway6(gwhw [6]byte) {
|
func (s *StackAsync) SetGateway6(gwhw [6]byte) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
s.link.SetGateway6(gwhw)
|
s.link.SetGateway6(gwhw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StackAsync) start() {
|
func (s *StackAsync) Gateway6() [6]byte {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
return s.link.Gateway6()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StackAsync) DialTCP(conn *tcp.Conn, localPort uint16, addrp netip.AddrPort) (err error) {
|
func (s *StackAsync) DialTCP(conn *tcp.Conn, localPort uint16, addrp netip.AddrPort) (err error) {
|
||||||
if !conn.State().IsClosed() {
|
|
||||||
return errors.New("conn not closed")
|
|
||||||
}
|
|
||||||
conn.Abort() // Conn is closed, safe to abort.
|
|
||||||
err = conn.OpenActive(localPort, addrp, tcp.Value(s.Prand32()))
|
err = conn.OpenActive(localPort, addrp, tcp.Value(s.Prand32()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = s.tcps.Register(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Abort()
|
conn.Abort()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StackAsync) ListenTCP(conn *tcp.Conn, localPort uint16) (err error) {
|
||||||
|
err = conn.OpenListen(localPort, tcp.Value(s.Prand32()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err = s.tcps.Register(conn)
|
err = s.tcps.Register(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Abort()
|
conn.Abort()
|
||||||
|
|||||||
+94
-16
@@ -4,9 +4,15 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/soypat/lneto"
|
||||||
|
"github.com/soypat/lneto/internet/pcap"
|
||||||
"github.com/soypat/lneto/tcp"
|
"github.com/soypat/lneto/tcp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
synack = tcp.FlagSYN | tcp.FlagACK
|
||||||
|
)
|
||||||
|
|
||||||
func TestABC(t *testing.T) {
|
func TestABC(t *testing.T) {
|
||||||
const seed = 1234
|
const seed = 1234
|
||||||
const MTU = 1500
|
const MTU = 1500
|
||||||
@@ -37,23 +43,8 @@ func TestABC(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// IMG_1084.MOV
|
|
||||||
|
|
||||||
const svPort = 80
|
const svPort = 80
|
||||||
var clconn tcp.Conn
|
|
||||||
err = clconn.Configure(tcp.ConnConfig{
|
|
||||||
RxBuf: make([]byte, MTU),
|
|
||||||
TxBuf: make([]byte, MTU),
|
|
||||||
TxPacketQueueSize: 4,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
err = client.DialTCP(&clconn, 1337, netip.AddrPortFrom(sv.Addr(), svPort))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var svconn tcp.Conn
|
var svconn tcp.Conn
|
||||||
err = svconn.Configure(tcp.ConnConfig{
|
err = svconn.Configure(tcp.ConnConfig{
|
||||||
RxBuf: make([]byte, MTU),
|
RxBuf: make([]byte, MTU),
|
||||||
@@ -63,5 +54,92 @@ func TestABC(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// clconn.OpenListen()
|
err = sv.ListenTCP(&svconn, svPort)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var clconn tcp.Conn
|
||||||
|
err = clconn.Configure(tcp.ConnConfig{
|
||||||
|
RxBuf: make([]byte, MTU),
|
||||||
|
TxBuf: make([]byte, MTU),
|
||||||
|
TxPacketQueueSize: 4,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
client.SetGateway6(sv.HardwareAddress())
|
||||||
|
sv.SetGateway6(client.HardwareAddress())
|
||||||
|
|
||||||
|
err = client.DialTCP(&clconn, 1337, netip.AddrPortFrom(sv.Addr(), svPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var expected = []struct {
|
||||||
|
fromClient bool
|
||||||
|
flags tcp.Flags
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
fromClient: true,
|
||||||
|
flags: tcp.FlagSYN,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fromClient: false,
|
||||||
|
flags: synack,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fromClient: true,
|
||||||
|
flags: tcp.FlagACK,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
var cap pcap.PacketBreakdown
|
||||||
|
var frms []pcap.Frame
|
||||||
|
var buf [MTU]byte
|
||||||
|
for _, action := range expected {
|
||||||
|
var n int
|
||||||
|
switch action.fromClient {
|
||||||
|
case true:
|
||||||
|
n, err = client.Encapsulate(buf[:], 0)
|
||||||
|
case false:
|
||||||
|
n, err = sv.Encapsulate(buf[:], 0)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if n == 0 {
|
||||||
|
t.Error("zero bits sent")
|
||||||
|
}
|
||||||
|
frms, err = cap.CaptureEthernet(frms[:0], buf[:n], 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
tfrm := getProtoFrame(frms, 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)
|
||||||
|
if tflags != action.flags {
|
||||||
|
t.Errorf("expected flags %s, got %s", action.flags.String(), tflags.String())
|
||||||
|
}
|
||||||
|
switch action.fromClient {
|
||||||
|
case true:
|
||||||
|
err = sv.Demux(buf[:], 0)
|
||||||
|
case false:
|
||||||
|
err = client.Demux(buf[:], 0)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProtoFrame(frms []pcap.Frame, proto any) *pcap.Frame {
|
||||||
|
for i := range frms {
|
||||||
|
if frms[i].Protocol == proto {
|
||||||
|
return &frms[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user