Sender retries

This commit is contained in:
Josh Deprez 2024-04-21 14:18:58 +10:00
parent e7d67344d3
commit 6abf714861
Signed by: josh
SSH key fingerprint: SHA256:zZji7w1Ilh2RuUpbQcqkLPrqmRwpiCSycbF2EfKm6Kw

View file

@ -62,18 +62,18 @@ type senderState int
const ( const (
ssUnconnected senderState = iota ssUnconnected senderState = iota
ssConnected ssConnected
ssWaitForRIAck1 ssWaitForRIRspAck
ssWaitForRIAck2 ssWaitForRIUpdAck
ssWaitForRIAck3 ssWaitForRDAck
) )
func (ss senderState) String() string { func (ss senderState) String() string {
return map[senderState]string{ return map[senderState]string{
ssUnconnected: "unconnected", ssUnconnected: "unconnected",
ssConnected: "connected", ssConnected: "connected",
ssWaitForRIAck1: "waiting for RI-Ack (1)", ssWaitForRIRspAck: "waiting for RI-Ack for RI-Rsp",
ssWaitForRIAck2: "waiting for RI-Ack (2)", ssWaitForRIUpdAck: "waiting for RI-Ack for RI-Upd",
ssWaitForRIAck3: "waiting for RI-Ack (3)", ssWaitForRDAck: "waiting for RI-Ack for RD",
}[ss] }[ss]
} }
@ -110,6 +110,8 @@ func (p *Peer) Handle(ctx context.Context) error {
lastUpdate := time.Now() lastUpdate := time.Now()
sendRetries := 0 sendRetries := 0
var lastRISent aurp.Packet
rstate := rsUnconnected rstate := rsUnconnected
sstate := ssUnconnected sstate := ssUnconnected
@ -129,7 +131,8 @@ func (p *Peer) Handle(ctx context.Context) error {
return ctx.Err() return ctx.Err()
} }
// Send a best-effort Router Down before returning // Send a best-effort Router Down before returning
if _, err := p.Send(p.Transport.NewRDPacket(aurp.ErrCodeNormalClose)); err != nil { lastRISent = p.Transport.NewRDPacket(aurp.ErrCodeNormalClose)
if _, err := p.Send(lastRISent); err != nil {
log.Printf("Couldn't send RD packet: %v", err) log.Printf("Couldn't send RD packet: %v", err)
} }
return ctx.Err() return ctx.Err()
@ -207,9 +210,9 @@ func (p *Peer) Handle(ctx context.Context) error {
// still in Wait For RI-Rsp // still in Wait For RI-Rsp
case rsUnconnected: case rsUnconnected:
// If sstate != ssUnconnected, send a null RI-Upd to check // Data receiver is unconnected. If data sender is connected,
// that the sender side is also unconnected // send a null RI-Upd to check if the sender is also unconnected
if sstate != ssUnconnected && time.Since(lastSend) > sendRetryTimer { if sstate == ssConnected && time.Since(lastSend) > sendRetryTimer {
if sendRetries >= sendRetryLimit { if sendRetries >= sendRetryLimit {
log.Printf("AURP Peer: Send retry limit reached while probing sender connect, closing connection") log.Printf("AURP Peer: Send retry limit reached while probing sender connect, closing connection")
} }
@ -219,11 +222,12 @@ func (p *Peer) Handle(ctx context.Context) error {
events := aurp.EventTuples{{ events := aurp.EventTuples{{
EventCode: aurp.EventCodeNull, EventCode: aurp.EventCodeNull,
}} }}
if _, err := p.Send(p.Transport.NewRIUpdPacket(events)); err != nil { lastRISent = p.Transport.NewRIUpdPacket(events)
if _, err := p.Send(lastRISent); err != nil {
log.Printf("AURP Peer: Couldn't send RI-Upd packet: %v", err) log.Printf("AURP Peer: Couldn't send RI-Upd packet: %v", err)
return err return err
} }
sstate = ssWaitForRIAck1 sstate = ssWaitForRIUpdAck
} }
if p.Reconnect { if p.Reconnect {
@ -254,19 +258,27 @@ func (p *Peer) Handle(ctx context.Context) error {
} }
// TODO: is there a routing update to send? // TODO: is there a routing update to send?
case ssWaitForRIAck1: case ssWaitForRIRspAck, ssWaitForRIUpdAck:
if time.Since(lastSend) <= sendRetryTimer { if time.Since(lastSend) <= sendRetryTimer {
break break
} }
// TODO: Re-send RI-Rsp if lastRISent == nil {
log.Print("AURP Peer: sender retry: lastRISent = nil?")
case ssWaitForRIAck2: continue
if time.Since(lastSend) <= sendRetryTimer { }
break if sendRetries >= sendRetryLimit {
log.Printf("AURP Peer: Send retry limit reached, closing connection")
sstate = ssUnconnected
continue
}
sendRetries++
lastSend = time.Now()
if _, err := p.Send(lastRISent); err != nil {
log.Printf("AURP Peer: Couldn't re-send %T: %v", lastRISent, err)
return err
} }
// TODO: Re-send RI-Upd
case ssWaitForRIAck3: case ssWaitForRDAck:
if time.Since(lastSend) <= sendRetryTimer { if time.Since(lastSend) <= sendRetryTimer {
break break
} }
@ -355,11 +367,12 @@ func (p *Peer) Handle(ctx context.Context) error {
}, },
} }
p.Transport.LocalSeq = 1 p.Transport.LocalSeq = 1
if _, err := p.Send(p.Transport.NewRIRspPacket(aurp.RoutingFlagLast, nets)); err != nil { lastRISent = p.Transport.NewRIRspPacket(aurp.RoutingFlagLast, nets)
if _, err := p.Send(lastRISent); err != nil {
log.Printf("AURP Peer: Couldn't send RI-Rsp packet: %v", err) log.Printf("AURP Peer: Couldn't send RI-Rsp packet: %v", err)
return err return err
} }
sstate = ssWaitForRIAck1 sstate = ssWaitForRIRspAck
case *aurp.RIRspPacket: case *aurp.RIRspPacket:
if rstate != rsWaitForRIRsp { if rstate != rsWaitForRIRsp {
@ -391,13 +404,13 @@ func (p *Peer) Handle(ctx context.Context) error {
case *aurp.RIAckPacket: case *aurp.RIAckPacket:
switch sstate { switch sstate {
case ssWaitForRIAck1: case ssWaitForRIRspAck:
// We sent an RI-Rsp, this is the RI-Ack we expected. // We sent an RI-Rsp, this is the RI-Ack we expected.
case ssWaitForRIAck2: case ssWaitForRIUpdAck:
// We sent an RI-Upd, this is the RI-Ack we expected. // We sent an RI-Upd, this is the RI-Ack we expected.
case ssWaitForRIAck3: case ssWaitForRDAck:
// We sent an RD... Why are we here? // We sent an RD... Why are we here?
continue continue