add dhcp failing test

This commit is contained in:
soypat
2025-06-17 02:07:11 -03:00
parent 47eae76dcf
commit 2133966a16
17 changed files with 596 additions and 195 deletions
+34
View File
@@ -104,6 +104,28 @@ func getNode(nodes []node, port uint16, protocol uint16) (node *node) {
return nil
}
func getEncapsulateNode(nodes *[]node, carrierData []byte, frameOffset int) (nodeIdx int, written int, err error) {
destroyed := false
for i := range *nodes {
node := &(*nodes)[i]
if checkNode(node) {
destroyed = true
node.destroy()
continue
}
written, err = node.encapsulate(carrierData, frameOffset)
if written > 0 {
return i, written, err
} else if err != nil {
}
}
if destroyed {
*nodes = nodesCompact(*nodes)
}
return -1, 0, nil
}
// destroy removes all references to underlying StackNode. Allows garbage collection of node if possible.
func (n *node) destroy() {
*n = node{}
@@ -116,5 +138,17 @@ func getNodeByProto(nodes []node, protocol uint16) int {
return i
}
}
return -1
}
func nodesCompact(nodes []node) []node {
nilOff := 0
for i := 0; i < len(nodes); i++ {
if !checkNode(&nodes[i]) {
nodes[nilOff] = nodes[i]
nilOff++
}
}
return nodes[:nilOff]
}
+1 -1
View File
@@ -123,7 +123,7 @@ func (listener *NodeTCPListener) Demux(carrierData []byte, tcpFrameOffset int) e
if err != nil {
return err
}
addr, _, err := internal.GetIPSourceAddr(carrierData)
addr, _, _, err := internal.GetIPSourceAddr(carrierData)
if err != nil {
return err
}
+16 -3
View File
@@ -18,6 +18,7 @@ var _ StackNode = (*StackIP)(nil)
type StackIP struct {
connID uint64
ipID uint16
ip [4]byte
validator lneto.Validator
handlers []node
@@ -136,24 +137,31 @@ func (sb *StackIP) Encapsulate(carrierData []byte, frameOffset int) (int, error)
ifrm, _ := ipv4.NewFrame(frame)
const ihl = 5
const headerlen = ihl * 4
const dontFrag = 0x4000
ifrm.SetVersionAndIHL(4, ihl)
ifrm.SetToS(0)
ifrm.SetID(0)
seed := sb.ipID + uint16(sb.connID)
id := internal.Prand16(seed)
ifrm.SetID(id)
ifrm.SetFlags(dontFrag)
*ifrm.SourceAddr() = sb.ip
sb.ipID = id
for i := range sb.handlers {
h := &sb.handlers[i]
proto := lneto.IPProto(h.proto)
n, err := h.encapsulate(frame[:], headerlen)
if err != nil {
if handleNodeError(&sb.handlers, i, err) {
println("NODE REMOVED", proto.String(), h.port)
h.destroy()
}
sb.error("StackIP:handle", slog.String("proto", proto.String()), slog.String("err", err.Error()))
continue
} else if n == 0 {
continue
}
const dontFrag = 0x4000
totalLen := n + headerlen
ifrm.SetTotalLength(uint16(totalLen))
ifrm.SetFlags(dontFrag)
ifrm.SetTTL(64)
ifrm.SetProtocol(proto)
ifrm.SetCRC(ifrm.CalculateHeaderCRC())
@@ -168,8 +176,13 @@ func (sb *StackIP) Encapsulate(carrierData []byte, frameOffset int) (int, error)
case lneto.IPProtoUDP:
ifrm.CRCWriteUDPPseudo(&crc)
ufrm, _ := udp.NewFrame(ifrm.Payload())
ufrm.SetLength(uint16(n))
ufrm.CRCWriteIPv4(&crc)
ufrm.SetCRC(crc.Sum16())
if n != int(ufrm.Length()) {
sb.error("StackIP:encaps", slog.Int("n", n), slog.Int("un", int(ufrm.Length())))
return 0, errors.New("invalid UDP length")
}
}
return totalLen, nil
}
+10 -7
View File
@@ -47,7 +47,7 @@ func (sudp *StackUDPPort) Demux(carrierData []byte, frameOffset int) error {
if sudp.rmport != 0 && src != sudp.rmport {
return nil // Not from our target remote port.
}
err = sudp.h.demux(ufrm.Payload(), 8)
err = sudp.h.demux(carrierData, frameOffset+8)
if err != nil {
if checkNodeErr(&sudp.h, err) {
sudp.h.destroy()
@@ -68,11 +68,14 @@ func (sudp *StackUDPPort) Encapsulate(carrierData []byte, frameOffset int) (int,
}
ufrm.SetSourcePort(sudp.h.port)
ufrm.SetDestinationPort(sudp.rmport)
n, err := sudp.h.encapsulate(carrierData[frameOffset:], 8)
if err != nil {
slog.Error("stackudp:demux", slog.String("err", err.Error()))
n, err := sudp.h.encapsulate(carrierData, frameOffset+8)
if n == 0 {
if err != nil {
slog.Error("stackudp:demux", slog.String("err", err.Error()))
}
return 0, err
}
ufrm.SetLength(8 + uint16(n))
// UDP CRC left to IP layer.
return n, err
// UDP CRC and length left to IP layer.
length := 8 + n
return length, err
}