Handle SIGINT, send RD

This commit is contained in:
Josh Deprez 2024-03-30 14:24:16 +11:00
parent 520046d86a
commit 64f491fcba
Signed by: josh
SSH key fingerprint: SHA256:zZji7w1Ilh2RuUpbQcqkLPrqmRwpiCSycbF2EfKm6Kw
3 changed files with 25 additions and 5 deletions

View file

@ -111,6 +111,17 @@ func (tr *Transport) NewOpenRspPacket(envFlags RoutingFlag, rateOrErr int16, opt
}
}
func (tr *Transport) NewRDPacket(errCode ErrorCode) *RDPacket {
return &RDPacket{
Header: Header{
TrHeader: tr.transaction(tr.LocalConnID),
CommandCode: CmdCodeRD,
Flags: 0,
},
ErrorCode: errCode,
}
}
func (tr *Transport) NewTicklePacket() *TicklePacket {
return &TicklePacket{
Header: Header{

13
main.go
View file

@ -5,6 +5,8 @@ import (
"flag"
"log"
"net"
"os"
"os/signal"
"regexp"
"gitea.drjosh.dev/josh/jrouter/aurp"
@ -18,8 +20,6 @@ func main() {
flag.Parse()
log.Println("jrouter")
ctx := context.Background()
cfg, err := loadConfig(*configFilePath)
if err != nil {
log.Fatalf("Couldn't load configuration file: %v", err)
@ -62,6 +62,9 @@ func main() {
defer ln.Close()
log.Printf("Listening on %v", ln.LocalAddr())
log.Println("Press ^C or send SIGINT to stop the router gracefully")
ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)
for _, peerStr := range cfg.Peers {
if !hasPortRE.MatchString(peerStr) {
peerStr += ":387"
@ -92,15 +95,15 @@ func main() {
}
// Incoming packet loop
pb := make([]byte, 65536)
for {
pktlen, raddr, readErr := ln.ReadFromUDP(pb)
pktbuf := make([]byte, 65536)
pktlen, raddr, readErr := ln.ReadFromUDP(pktbuf)
// net.PacketConn.ReadFrom: "Callers should always process
// the n > 0 bytes returned before considering the error err."
log.Printf("Received packet of length %d from %v", pktlen, raddr)
dh, pkt, parseErr := aurp.ParsePacket(pb[:pktlen])
dh, pkt, parseErr := aurp.ParsePacket(pktbuf[:pktlen])
if parseErr != nil {
log.Printf("Failed to parse packet: %v", parseErr)
continue

View file

@ -32,6 +32,8 @@ func (p *peer) handle(ctx context.Context) error {
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
p.lastHeardFrom = time.Now()
// Write an Open-Req packet
n, err := p.send(p.tr.NewOpenReqPacket(nil))
if err != nil {
@ -43,6 +45,10 @@ func (p *peer) handle(ctx context.Context) error {
for {
select {
case <-ctx.Done():
// Send a best-effort Router Down before returning
if _, err := p.send(p.tr.NewRDPacket(aurp.ErrCodeNormalClose)); err != nil {
log.Printf("Couldn't send RD packet: %v", err)
}
return ctx.Err()
case <-ticker.C: