ethernet: MTU semantic meaning corrections, add FCS logic (#28)

This commit is contained in:
Pat Whittingslow
2026-01-26 16:45:35 -03:00
committed by GitHub
parent 6a6097a9ac
commit 85f018a02c
10 changed files with 241 additions and 25 deletions
+2
View File
@@ -325,6 +325,8 @@ func (s *StackAsync) StartLookupIP(host string) error {
return err
}
// EDNS0 buffer size: MTU minus overhead for IP+UDP headers and safety margin.
// 100 bytes covers IPv4 max header (60) + UDP (8) + 32 byte margin.
s.ednsopt.SetEDNS0(uint16(s.link.MTU())-100, 0, 0, nil)
rand := s.prand32()
err = s.dns.StartResolve(uint16(rand>>1)+1024, uint16(rand), dns.ResolveConfig{
+13 -10
View File
@@ -11,15 +11,18 @@ import (
"testing"
"time"
"github.com/soypat/lneto/ethernet"
"github.com/soypat/lneto/tcp"
)
func TestTCPListener_ConcurrentEcho(t *testing.T) {
const (
numClients = 10
serverPort = 8080
MTU = 1500
seed = 1
numClients = 10
serverPort = 8080
MTU = 1500
carrierSize = MTU + ethernet.MaxOverheadSize
tcpBufSize = MTU
seed = 1
)
// 1. Setup server stack with tcp.Listener.
@@ -63,7 +66,7 @@ func TestTCPListener_ConcurrentEcho(t *testing.T) {
// 2. Setup client stacks (one per client).
clientStacks := make([]StackAsync, numClients)
clientConns := make([]tcp.Conn, numClients)
connBufs := make([]byte, numClients*MTU*2) // RX+TX buffer space for all clients
connBufs := make([]byte, numClients*tcpBufSize*2) // RX+TX buffer space for all clients
for i := range clientStacks {
clientMAC := [6]byte{0xaa, 0xbb, 0xcc, 0x00, 0x01, byte(i + 1)}
@@ -83,10 +86,10 @@ func TestTCPListener_ConcurrentEcho(t *testing.T) {
clientStacks[i].SetGateway6(serverMAC)
// Configure client connection buffers.
bufOff := i * MTU * 2
bufOff := i * tcpBufSize * 2
err = clientConns[i].Configure(tcp.ConnConfig{
RxBuf: connBufs[bufOff : bufOff+MTU],
TxBuf: connBufs[bufOff+MTU : bufOff+2*MTU],
RxBuf: connBufs[bufOff : bufOff+tcpBufSize],
TxBuf: connBufs[bufOff+tcpBufSize : bufOff+2*tcpBufSize],
TxPacketQueueSize: 4,
})
if err != nil {
@@ -140,7 +143,7 @@ func TestTCPListener_ConcurrentEcho(t *testing.T) {
func kernelLoop(ctx context.Context, server *StackAsync, clients []StackAsync) {
const MTU = 1500
const carrierDataSize = MTU + 14
const carrierDataSize = MTU + ethernet.MaxOverheadSize
buf := make([]byte, carrierDataSize)
rng := rand.New(rand.NewSource(1)) // Seed 1 for deterministic but randomized order
order := make([]int, len(clients))
@@ -174,7 +177,7 @@ func kernelLoop(ctx context.Context, server *StackAsync, clients []StackAsync) {
func routePacketToClient(pkt []byte, clients []StackAsync) {
// Extract destination IP from IPv4 header (offset 16-19 in IP header, after 14 byte Ethernet header).
if len(pkt) < 34 { // 14 ethernet + 20 min IP header
if len(pkt) < 20+ethernet.MaxOverheadSize { // 20 min IP header
return
}
dstIP := netip.AddrFrom4([4]byte{pkt[30], pkt[31], pkt[32], pkt[33]})
+1 -1
View File
@@ -47,7 +47,7 @@ func TestDNS_QueryReceivesAnswer(t *testing.T) {
}
// Client sends DNS query.
const carrierDataSize = MTU + 14
const carrierDataSize = MTU + ethernet.MaxOverheadSize
var buf [carrierDataSize]byte
n, err := client.Encapsulate(buf[:], -1, 0)
if err != nil {
+3
View File
@@ -5,12 +5,14 @@ import (
"testing"
"time"
"github.com/soypat/lneto/ethernet"
"github.com/soypat/lneto/tcp"
)
func TestStackAsyncListener_SingleConnection(t *testing.T) {
const seed int64 = 1234
const MTU = 1500
const carrierSize = MTU + ethernet.MaxOverheadSize
const svPort = 80
const clPort = 1337
@@ -121,6 +123,7 @@ func TestStackAsyncListener_SingleConnection(t *testing.T) {
func TestStackAsyncListener_MultiSequentialConn(t *testing.T) {
const seed int64 = 1234
const MTU = 1500
const carrierSize = MTU + ethernet.MaxOverheadSize
const svPort = 80
const clPort = 1337
const poolsize = 10
+1 -1
View File
@@ -217,7 +217,7 @@ func newTCPStacks(t *testing.T, randSeed int64, mtu int) (s1, s2 *StackAsync, c1
}
func testerFrom(t *testing.T, mtu int) *tester {
carrierDataSize := mtu + 14
carrierDataSize := mtu + ethernet.MaxOverheadSize
return &tester{
t: t,
buf: make([]byte, carrierDataSize),