mirror of
https://github.com/soypat/lneto.git
synced 2026-08-16 12:53:26 +00:00
begin testing tcp listener (not working)
This commit is contained in:
+1
-1
@@ -150,7 +150,7 @@ func (c *Handler) Recv(b []byte) error {
|
||||
var vld lneto.Validator
|
||||
afrm.ValidateSize(&vld)
|
||||
if vld.HasError() {
|
||||
return vld.Err()
|
||||
return vld.ErrPop()
|
||||
}
|
||||
htype, hlen := afrm.Hardware()
|
||||
if htype != c.htype || int(hlen) != len(c.ourHWAddr) {
|
||||
|
||||
+2
-2
@@ -114,8 +114,8 @@ func validateARP(t *testing.T, buf []byte) {
|
||||
var vld lneto.Validator
|
||||
afrm.ValidateSize(&vld)
|
||||
if vld.HasError() {
|
||||
t.Errorf("invalid arp: %s", vld.Err())
|
||||
} else if err := vld.Err(); err != nil {
|
||||
t.Errorf("invalid arp: %s", vld.ErrPop())
|
||||
} else if err := vld.ErrPop(); err != nil {
|
||||
panic("unreachable: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
+71
-16
@@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
@@ -49,7 +51,7 @@ func main() {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
handler, err := stack.OpenPassiveTCP(addrPort.Port(), iss)
|
||||
listener, err := stack.OpenTCPListener(addrPort.Port())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -62,6 +64,7 @@ func main() {
|
||||
const standbyDuration = 5 * time.Second
|
||||
lastHit := time.Now().Add(-standbyDuration)
|
||||
var cap pcap.PacketBreakdown
|
||||
var conn *tcp.Conn
|
||||
for {
|
||||
nread, err := tap.Read(buf[:])
|
||||
if err != nil {
|
||||
@@ -82,7 +85,25 @@ func main() {
|
||||
lg.Error("recv", slog.String("err", err.Error()), slog.Int("plen", nread))
|
||||
}
|
||||
}
|
||||
doHTTP(handler, &hdr)
|
||||
if conn == nil && listener.NumberOfReadyToAccept() > 0 {
|
||||
conn, err = listener.TryAccept()
|
||||
if err != nil {
|
||||
lg.Error("tryaccept", slog.String("err", err.Error()))
|
||||
}
|
||||
lg.Info("ACCEPT!")
|
||||
}
|
||||
if conn != nil {
|
||||
done, err := doHTTP(conn, &hdr)
|
||||
if done {
|
||||
lg.Info("close forever")
|
||||
conn.Close()
|
||||
conn = nil
|
||||
}
|
||||
if err != nil {
|
||||
lg.Error("doHTTP", slog.String("err", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
nw, err := stack.ethernet.Encapsulate(buf[:], 0)
|
||||
if err != nil {
|
||||
lg.Error("handle", slog.String("err", err.Error()))
|
||||
@@ -115,23 +136,21 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func doHTTP(conn *tcp.Conn, hdr *httpraw.Header) error {
|
||||
func doHTTP(conn *tcp.Conn, hdr *httpraw.Header) (done bool, err error) {
|
||||
const asRequest = false
|
||||
if conn.State() != tcp.StateEstablished || conn.BufferedInput() == 0 {
|
||||
return nil // No data yet.
|
||||
return false, nil // No data yet.
|
||||
}
|
||||
fmt.Println("state is established; check request and send response")
|
||||
_, err := hdr.ReadFromLimited(conn, hdr.BufferFree())
|
||||
_, err = hdr.ReadFromLimited(conn, hdr.BufferFree())
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
needMore, err := hdr.TryParse(asRequest)
|
||||
if err != nil {
|
||||
if !needMore {
|
||||
fmt.Println("IT's SO GOVER")
|
||||
conn.Close()
|
||||
}
|
||||
return err
|
||||
if needMore {
|
||||
return false, nil
|
||||
} else if err != nil {
|
||||
return true, err
|
||||
}
|
||||
// HTTP parsed succesfully!
|
||||
fmt.Println("GOT HTTP:\n", hdr.String())
|
||||
@@ -141,18 +160,18 @@ func doHTTP(conn *tcp.Conn, hdr *httpraw.Header) error {
|
||||
data := `{"ok":true}`
|
||||
response, err := hdr.AppendResponse(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
return true, err
|
||||
}
|
||||
response = append(response, data...)
|
||||
_, err = conn.Write(response)
|
||||
if err != nil {
|
||||
return err
|
||||
return true, err
|
||||
}
|
||||
err = conn.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
return true, err
|
||||
}
|
||||
return nil
|
||||
return true, nil
|
||||
}
|
||||
|
||||
type Stack struct {
|
||||
@@ -198,6 +217,7 @@ func (stack *Stack) Reset(ourMAC, gwMAC [6]byte, ip netip.Addr, mtu int) (err er
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -209,6 +229,19 @@ func (stack *Stack) Send(b []byte) (int, error) {
|
||||
return stack.ethernet.Encapsulate(b, 0)
|
||||
}
|
||||
|
||||
func (stack *Stack) OpenTCPListener(port uint16) (*internet.NodeTCPListener, error) {
|
||||
var listener internet.NodeTCPListener
|
||||
err := listener.Reset(port, naiveTCPPool{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = stack.tcpports.Register(&listener)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &listener, nil
|
||||
}
|
||||
|
||||
func (stack *Stack) OpenPassiveTCP(port uint16, iss tcp.Value) (*tcp.Conn, error) {
|
||||
mtu := stack.ethernet.MTU()
|
||||
conn := new(tcp.Conn)
|
||||
@@ -250,3 +283,25 @@ func getTCPFlags(frames []pcap.Frame, pkt []byte) (flags tcp.Flags) {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type naiveTCPPool struct {
|
||||
}
|
||||
|
||||
func (naiveTCPPool) GetTCP() (*tcp.Conn, tcp.Value) {
|
||||
var buf [4]byte
|
||||
rand.Read(buf[:])
|
||||
randVal := binary.LittleEndian.Uint32(buf[:])
|
||||
var conn tcp.Conn
|
||||
err := conn.Configure(&tcp.ConnConfig{
|
||||
RxBuf: make([]byte, 1024),
|
||||
TxBuf: make([]byte, 1024),
|
||||
TxPacketQueueSize: 3,
|
||||
Logger: slog.Default(),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &conn, tcp.Value(randVal)
|
||||
}
|
||||
|
||||
func (naiveTCPPool) PutTCP(*tcp.Conn) {}
|
||||
|
||||
@@ -268,7 +268,7 @@ func (ls *LinkStack) RecvEth(ethFrame []byte) (err error) {
|
||||
goto DROP
|
||||
}
|
||||
efrm.ValidateSize(&vld)
|
||||
if err := vld.Err(); err != nil {
|
||||
if err := vld.ErrPop(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -143,15 +143,15 @@ func (gen *PacketGen) AppendRandomIPv4TCPPacket(dst []byte, rng *rand.Rand, seg
|
||||
}
|
||||
var vld lneto.Validator
|
||||
efrm.ValidateSize(&vld)
|
||||
if err = vld.Err(); err != nil {
|
||||
if err = vld.ErrPop(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ifrm.ValidateExceptCRC(&vld)
|
||||
if err = vld.Err(); err != nil {
|
||||
if err = vld.ErrPop(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tfrm.ValidateSize(&vld)
|
||||
if err = vld.Err(); err != nil {
|
||||
if err = vld.ErrPop(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return dst
|
||||
|
||||
@@ -31,7 +31,7 @@ func (narp *NodeARP) Demux(EtherFrame []byte, arpOff int) error {
|
||||
}
|
||||
afrm.ValidateSize(&narp.vld)
|
||||
if narp.vld.HasError() {
|
||||
slog.Error("invalid-ARP", slog.String("err", narp.vld.Err().Error()))
|
||||
slog.Error("invalid-ARP", slog.String("err", narp.vld.ErrPop().Error()))
|
||||
return nil
|
||||
}
|
||||
return narp.handler.Recv(EtherFrame[arpOff:])
|
||||
|
||||
@@ -65,9 +65,36 @@ func (listener *NodeTCPListener) Reset(port uint16, pool tcpPool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (listener *NodeTCPListener) NumberOfReadyToAccept() (nready int) {
|
||||
if listener.isClosed() {
|
||||
return 0
|
||||
}
|
||||
for _, conn := range listener.ready {
|
||||
if conn == nil {
|
||||
continue
|
||||
}
|
||||
nready++
|
||||
}
|
||||
return nready
|
||||
}
|
||||
|
||||
func (listener *NodeTCPListener) TryAccept() (*tcp.Conn, error) {
|
||||
if listener.isClosed() {
|
||||
return nil, net.ErrClosed
|
||||
}
|
||||
for i, conn := range listener.ready {
|
||||
if conn == nil {
|
||||
continue
|
||||
}
|
||||
listener.accepted = append(listener.accepted, conn)
|
||||
listener.ready[i] = nil // discard from ready.
|
||||
return conn, nil
|
||||
}
|
||||
return nil, errors.New("no conns available")
|
||||
}
|
||||
|
||||
func (listener *NodeTCPListener) AcceptRaw() (*tcp.Conn, error) {
|
||||
connid := listener.connID
|
||||
|
||||
for {
|
||||
if listener.isClosed() || connid != listener.connID {
|
||||
return nil, net.ErrClosed
|
||||
|
||||
@@ -34,7 +34,7 @@ func (pc *PacketBreakdown) CaptureEthernet(dst []Frame, pkt []byte, bitOffset in
|
||||
}
|
||||
efrm.ValidateSize(pc.validator())
|
||||
if pc.validator().HasError() {
|
||||
return dst, pc.validator().Err()
|
||||
return dst, pc.validator().ErrPop()
|
||||
}
|
||||
|
||||
finfo := Frame{
|
||||
@@ -61,6 +61,8 @@ func (pc *PacketBreakdown) CaptureEthernet(dst []Frame, pkt []byte, bitOffset in
|
||||
dst, err = pc.CaptureARP(dst, pkt, end)
|
||||
case ethernet.TypeIPv4:
|
||||
dst, err = pc.CaptureIPv4(dst, pkt, end)
|
||||
case ethernet.TypeIPv6:
|
||||
dst, err = pc.CaptureIPv6(dst, pkt, end)
|
||||
default:
|
||||
dst = append(dst, remainingFrameInfo(etype, FieldClassPayload, end, octet*len(pkt)))
|
||||
}
|
||||
@@ -77,7 +79,7 @@ func (pc *PacketBreakdown) CaptureARP(dst []Frame, pkt []byte, bitOffset int) ([
|
||||
}
|
||||
afrm.ValidateSize(pc.validator())
|
||||
if pc.validator().HasError() {
|
||||
return dst, pc.validator().Err()
|
||||
return dst, pc.validator().ErrPop()
|
||||
}
|
||||
|
||||
finfo := Frame{
|
||||
@@ -129,7 +131,7 @@ func (pc *PacketBreakdown) CaptureIPv6(dst []Frame, pkt []byte, bitOffset int) (
|
||||
}
|
||||
ifrm6.ValidateSize(pc.validator())
|
||||
if pc.validator().HasError() {
|
||||
return dst, pc.validator().Err()
|
||||
return dst, pc.validator().ErrPop()
|
||||
}
|
||||
finfo := Frame{
|
||||
Protocol: ethernet.TypeIPv6,
|
||||
@@ -138,7 +140,7 @@ func (pc *PacketBreakdown) CaptureIPv6(dst []Frame, pkt []byte, bitOffset int) (
|
||||
finfo.Fields = append(finfo.Fields, baseIPv6Fields[:]...)
|
||||
dst = append(dst, finfo)
|
||||
proto := ifrm6.NextHeader()
|
||||
end := 40 * octet
|
||||
end := bitOffset + 40*octet
|
||||
return pc.captureIPProto(proto, dst, pkt, end)
|
||||
}
|
||||
|
||||
@@ -152,7 +154,7 @@ func (pc *PacketBreakdown) CaptureIPv4(dst []Frame, pkt []byte, bitOffset int) (
|
||||
}
|
||||
ifrm4.ValidateSize(pc.validator())
|
||||
if pc.validator().HasError() {
|
||||
return dst, pc.validator().Err()
|
||||
return dst, pc.validator().ErrPop()
|
||||
}
|
||||
finfo := Frame{
|
||||
Protocol: ethernet.TypeIPv4,
|
||||
@@ -195,7 +197,7 @@ func (pc *PacketBreakdown) CaptureTCP(dst []Frame, pkt []byte, bitOffset int) ([
|
||||
}
|
||||
tfrm.ValidateSize(pc.validator())
|
||||
if pc.validator().HasError() {
|
||||
return dst, pc.validator().Err()
|
||||
return dst, pc.validator().ErrPop()
|
||||
}
|
||||
end := bitOffset + octet*tfrm.HeaderLength()
|
||||
finfo := Frame{
|
||||
@@ -232,7 +234,7 @@ func (pc *PacketBreakdown) CaptureUDP(dst []Frame, pkt []byte, bitOffset int) ([
|
||||
}
|
||||
ufrm.ValidateSize(pc.validator())
|
||||
if pc.validator().HasError() {
|
||||
return dst, pc.validator().Err()
|
||||
return dst, pc.validator().ErrPop()
|
||||
}
|
||||
finfo := Frame{
|
||||
Protocol: lneto.IPProtoUDP,
|
||||
|
||||
@@ -77,7 +77,7 @@ func (ls *StackEthernet) Demux(carrierData []byte, frameOffset int) (err error)
|
||||
}
|
||||
efrm.ValidateSize(&vld)
|
||||
if vld.HasError() {
|
||||
return vld.Err()
|
||||
return vld.ErrPop()
|
||||
}
|
||||
|
||||
for i := range ls.handlers {
|
||||
|
||||
@@ -78,7 +78,7 @@ func (sb *StackIP) Demux(carrierData []byte, offset int) error {
|
||||
{
|
||||
sb.validator.ResetErr()
|
||||
ifrm.ValidateExceptCRC(&sb.validator)
|
||||
if err = sb.validator.Err(); err != nil {
|
||||
if err = sb.validator.ErrPop(); err != nil {
|
||||
return err
|
||||
}
|
||||
gotCRC := ifrm.CRC()
|
||||
|
||||
+2
-2
@@ -45,8 +45,8 @@ func TestFrame(t *testing.T) {
|
||||
wantDst := *dst
|
||||
ifrm.ValidateExceptCRC(v)
|
||||
ifrm.ValidateSize(v)
|
||||
if v.Err() != nil {
|
||||
t.Error(v.Err())
|
||||
if v.ErrPop() != nil {
|
||||
t.Error(v.ErrPop())
|
||||
}
|
||||
|
||||
// OPTION+PAYLOAD VALIDATION:
|
||||
|
||||
+1
-1
@@ -137,7 +137,7 @@ func TestIPv4TCPChecksum(t *testing.T) {
|
||||
ifrm.ValidateSize(&vld)
|
||||
tfrm, _ := tcp.NewFrame(ifrm.Payload())
|
||||
tfrm.ValidateExceptCRC(&vld)
|
||||
if err := vld.Err(); err != nil {
|
||||
if err := vld.ErrPop(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wantCRC := ifrm.CRC()
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ func (h *Handler) Recv(incomingPacket []byte) error {
|
||||
return err
|
||||
}
|
||||
tfrm.ValidateExceptCRC(&h.validator)
|
||||
err = h.validator.Err()
|
||||
err = h.validator.ErrPop()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+5
-5
@@ -596,8 +596,8 @@ func parseSegment(t *testing.T, b []byte) (tcp.Segment, []byte) {
|
||||
t.Fatalf("not IPv4")
|
||||
}
|
||||
efrm.ValidateSize(&vld)
|
||||
if err := vld.Err(); err != nil {
|
||||
t.Fatal(vld.Err())
|
||||
if err := vld.ErrPop(); err != nil {
|
||||
t.Fatal(vld.ErrPop())
|
||||
}
|
||||
ifrm, err := ipv4.NewFrame(efrm.Payload())
|
||||
if err != nil {
|
||||
@@ -611,8 +611,8 @@ func parseSegment(t *testing.T, b []byte) (tcp.Segment, []byte) {
|
||||
t.Fatal("invalid IP version", v)
|
||||
}
|
||||
ifrm.ValidateSize(&vld)
|
||||
if err := vld.Err(); err != nil {
|
||||
t.Fatal(vld.Err())
|
||||
if err := vld.ErrPop(); err != nil {
|
||||
t.Fatal(vld.ErrPop())
|
||||
}
|
||||
|
||||
ipl := ifrm.Payload()
|
||||
@@ -621,7 +621,7 @@ func parseSegment(t *testing.T, b []byte) (tcp.Segment, []byte) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tfrm.ValidateSize(&vld)
|
||||
if err := vld.Err(); err != nil {
|
||||
if err := vld.ErrPop(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_ = tfrm.String()
|
||||
|
||||
@@ -50,6 +50,7 @@ type ringidx struct {
|
||||
// Reset resets the RingTx's internal state to use buf as the main ring buffer and creates or reuses
|
||||
// the packet ring buffer.
|
||||
func (rtx *ringTx) Reset(buf []byte, maxqueuedPackets int, seq Value) error {
|
||||
buf = buf[:len(buf):len(buf)] // safely omit capacity section.
|
||||
if maxqueuedPackets <= 0 {
|
||||
return errors.New("queued packets <=0")
|
||||
} else if len(buf) < minBufferSize || len(buf) < maxqueuedPackets {
|
||||
|
||||
+8
-5
@@ -39,13 +39,16 @@ func (v *Validator) HasError() bool {
|
||||
return len(v.accum) != 0
|
||||
}
|
||||
|
||||
func (v *Validator) Err() error {
|
||||
// ErrPop returns the error(s) accumulated in the validator and clears them.
|
||||
func (v *Validator) ErrPop() (err error) {
|
||||
if len(v.accum) == 1 {
|
||||
return v.accum[0]
|
||||
} else if len(v.accum) == 0 {
|
||||
return nil
|
||||
err = v.accum[0]
|
||||
v.ResetErr()
|
||||
} else if len(v.accum) > 0 {
|
||||
err = errors.Join(v.accum...)
|
||||
v.ResetErr()
|
||||
}
|
||||
return errors.Join(v.accum...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (v *Validator) gotErr(err error) {
|
||||
|
||||
Reference in New Issue
Block a user