mirror of
https://github.com/soypat/lneto.git
synced 2026-09-03 13:29:02 +00:00
add dhcp failing test
This commit is contained in:
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user