mirror of
https://github.com/soypat/lneto.git
synced 2026-08-20 14:39:02 +00:00
continue reworking StackNode implementations
This commit is contained in:
+25
-11
@@ -9,6 +9,7 @@ import (
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
connID uint64
|
||||
ourHWAddr []byte
|
||||
ourProtoAddr []byte
|
||||
htype uint16
|
||||
@@ -26,22 +27,31 @@ type HandlerConfig struct {
|
||||
ProtocolType ethernet.Type
|
||||
}
|
||||
|
||||
func NewHandler(cfg HandlerConfig) (*Handler, error) {
|
||||
func (c *Handler) Reset(cfg HandlerConfig) error {
|
||||
if len(cfg.HardwareAddr) == 0 || len(cfg.HardwareAddr) > 255 ||
|
||||
len(cfg.ProtocolAddr) == 0 || len(cfg.ProtocolAddr) > 255 {
|
||||
return nil, errors.New("invalid Handler address config")
|
||||
return errors.New("invalid Handler address config")
|
||||
} else if cfg.MaxQueries <= 0 || cfg.MaxPending <= 0 {
|
||||
return nil, errors.New("invalid Handler query or pending config")
|
||||
return errors.New("invalid Handler query or pending config")
|
||||
}
|
||||
h := &Handler{
|
||||
pending: make([][sizeHeaderv6]byte, 0, cfg.MaxPending),
|
||||
*c = Handler{
|
||||
connID: c.connID + 1,
|
||||
ourHWAddr: c.ourHWAddr[:0],
|
||||
ourProtoAddr: c.ourProtoAddr[:0],
|
||||
htype: cfg.HardwareType,
|
||||
protoType: cfg.ProtocolType,
|
||||
ourHWAddr: cfg.HardwareAddr,
|
||||
ourProtoAddr: cfg.ProtocolAddr,
|
||||
queries: make([]queryResult, 0, cfg.MaxQueries),
|
||||
pending: c.pending[:0],
|
||||
queries: c.queries[:0],
|
||||
}
|
||||
return h, nil
|
||||
c.ourHWAddr = append(c.ourHWAddr, cfg.HardwareAddr...)
|
||||
c.ourProtoAddr = append(c.ourProtoAddr, cfg.ProtocolAddr...)
|
||||
if cap(c.pending) < cfg.MaxPending {
|
||||
c.pending = make([][52]byte, cfg.MaxPending)[:0]
|
||||
}
|
||||
if cap(c.queries) < cfg.MaxQueries {
|
||||
c.queries = make([]queryResult, cfg.MaxQueries)[:0]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type queryResult struct {
|
||||
@@ -50,8 +60,8 @@ type queryResult struct {
|
||||
querysent bool
|
||||
}
|
||||
|
||||
// ResetState drops pending queries and incoming requests.
|
||||
func (c *Handler) ResetState() {
|
||||
// AbortPending drops pending queries and incoming requests.
|
||||
func (c *Handler) AbortPending() {
|
||||
c.pending = c.pending[:0]
|
||||
c.queries = c.queries[:0]
|
||||
}
|
||||
@@ -60,6 +70,10 @@ func (c *Handler) expectSize() int {
|
||||
return sizeHeader + 2*len(c.ourHWAddr) + 2*len(c.ourProtoAddr)
|
||||
}
|
||||
|
||||
func (c *Handler) ConnectionID() *uint64 {
|
||||
return &c.connID
|
||||
}
|
||||
|
||||
func (c *Handler) QueryResult(protoAddr []byte) (hwAddr []byte, err error) {
|
||||
for i := range c.queries {
|
||||
if bytes.Equal(protoAddr, c.queries[i].protoaddr) {
|
||||
|
||||
+22
-2
@@ -5,11 +5,13 @@ import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/soypat/lneto"
|
||||
"github.com/soypat/lneto/ethernet"
|
||||
)
|
||||
|
||||
func TestHandler(t *testing.T) {
|
||||
c1, err := NewHandler(HandlerConfig{
|
||||
var c1, c2 Handler
|
||||
err := c1.Reset(HandlerConfig{
|
||||
HardwareAddr: []byte{0xde, 0xad, 0xbe, 0xef, 0x00, 0x00},
|
||||
ProtocolAddr: []byte{192, 168, 1, 1},
|
||||
MaxQueries: 1,
|
||||
@@ -20,7 +22,7 @@ func TestHandler(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
c2, err := NewHandler(HandlerConfig{
|
||||
err = c2.Reset(HandlerConfig{
|
||||
HardwareAddr: []byte{0xc0, 0xff, 0xee, 0xc0, 0xff, 0xee},
|
||||
ProtocolAddr: []byte{192, 168, 1, 2},
|
||||
MaxQueries: 1,
|
||||
@@ -58,6 +60,7 @@ func TestHandler(t *testing.T) {
|
||||
} else if n == 0 {
|
||||
t.Fatal("expected send of data after first query")
|
||||
}
|
||||
validateARP(t, buf[:])
|
||||
err = c2.Recv(buf[:n]) // Receive request.
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -69,6 +72,7 @@ func TestHandler(t *testing.T) {
|
||||
} else if n == 0 {
|
||||
t.Fatal("got no response to request")
|
||||
}
|
||||
validateARP(t, buf[:])
|
||||
n, err = c2.Send(discard[:]) // Double tap check, should send nothing.
|
||||
if err != nil {
|
||||
t.Fatal("double tap send error:", err)
|
||||
@@ -99,3 +103,19 @@ func TestHandler(t *testing.T) {
|
||||
t.Fatal("expected no data")
|
||||
}
|
||||
}
|
||||
|
||||
func validateARP(t *testing.T, buf []byte) {
|
||||
t.Helper()
|
||||
afrm, err := NewFrame(buf)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
var vld lneto.Validator
|
||||
afrm.ValidateSize(&vld)
|
||||
if vld.HasError() {
|
||||
t.Errorf("invalid arp: %s", vld.Err())
|
||||
} else if err := vld.Err(); err != nil {
|
||||
panic("unreachable: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user