Add ZI-Rsp handling on RI-Ack

This commit is contained in:
Josh Deprez 2024-03-30 20:27:24 +11:00
parent f5527d6db2
commit 21fcf11e5e
Signed by: josh
SSH key fingerprint: SHA256:zZji7w1Ilh2RuUpbQcqkLPrqmRwpiCSycbF2EfKm6Kw
3 changed files with 85 additions and 11 deletions

View file

@ -111,6 +111,17 @@ func (tr *Transport) NewOpenRspPacket(envFlags RoutingFlag, rateOrErr int16, opt
} }
} }
func (tr *Transport) NewRIRspPacket(connID, seq uint16, last RoutingFlag, nets NetworkTuples) *RIRspPacket {
return &RIRspPacket{
Header: Header{
TrHeader: tr.sequenced(connID, seq),
CommandCode: CmdCodeRIRsp,
Flags: last,
},
Networks: nets,
}
}
func (tr *Transport) NewRIAckPacket(connID, seq uint16, szi RoutingFlag) *RIAckPacket { func (tr *Transport) NewRIAckPacket(connID, seq uint16, szi RoutingFlag) *RIAckPacket {
return &RIAckPacket{ return &RIAckPacket{
Header: Header{ Header: Header{
@ -121,6 +132,29 @@ func (tr *Transport) NewRIAckPacket(connID, seq uint16, szi RoutingFlag) *RIAckP
} }
} }
func (tr *Transport) NewZIRspPacket(zones ZoneTuples) *ZIRspPacket {
nns := make(map[uint16]struct{})
for _, z := range zones {
nns[z.Network] = struct{}{}
}
// Only one network: use extended
// More than one network: use non-extended
subcode := SubcodeZoneInfoExt
if len(nns) != 1 {
subcode = SubcodeZoneInfoNonExt
}
return &ZIRspPacket{
Header: Header{
TrHeader: tr.transaction(tr.RemoteConnID),
CommandCode: CmdCodeZoneRsp,
Flags: 0,
},
Subcode: subcode,
Zones: zones,
}
}
func (tr *Transport) NewRDPacket(errCode ErrorCode) *RDPacket { func (tr *Transport) NewRDPacket(errCode ErrorCode) *RDPacket {
return &RDPacket{ return &RDPacket{
Header: Header{ Header: Header{

16
main.go
View file

@ -95,19 +95,18 @@ func main() {
} }
log.Printf("resolved %q to %v", peerStr, raddr) log.Printf("resolved %q to %v", peerStr, raddr)
tr := &aurp.Transport{
LocalDI: localDI,
RemoteDI: aurp.IPDomainIdentifier(raddr.IP),
LocalConnID: nextConnID,
}
nextConnID++
peer := &peer{ peer := &peer{
tr: tr, cfg: cfg,
tr: &aurp.Transport{
LocalDI: localDI,
RemoteDI: aurp.IPDomainIdentifier(raddr.IP),
LocalConnID: nextConnID,
},
conn: ln, conn: ln,
raddr: raddr, raddr: raddr,
recv: make(chan aurp.Packet, 1024), recv: make(chan aurp.Packet, 1024),
} }
nextConnID++
goHandler(peer) goHandler(peer)
peers[udpAddrFromNet(raddr)] = peer peers[udpAddrFromNet(raddr)] = peer
} }
@ -161,6 +160,7 @@ func main() {
// New peer! // New peer!
nextConnID++ nextConnID++
pr = &peer{ pr = &peer{
cfg: cfg,
tr: &aurp.Transport{ tr: &aurp.Transport{
LocalDI: localDI, LocalDI: localDI,
RemoteDI: dh.SourceDI, // platinum rule RemoteDI: dh.SourceDI, // platinum rule

46
peer.go
View file

@ -59,6 +59,7 @@ func (ss senderState) String() string {
} }
type peer struct { type peer struct {
cfg *config
tr *aurp.Transport tr *aurp.Transport
conn *net.UDPConn conn *net.UDPConn
raddr *net.UDPAddr raddr *net.UDPAddr
@ -225,7 +226,17 @@ func (p *peer) handle(ctx context.Context) error {
log.Printf("Received RI-Req but was not expecting one (sender state was %v)", sstate) log.Printf("Received RI-Req but was not expecting one (sender state was %v)", sstate)
} }
// TODO: Respond with RI-Rsp nets := aurp.NetworkTuples{
{
RangeStart: p.cfg.EtherTalk.NetStart,
RangeEnd: p.cfg.EtherTalk.NetEnd,
Distance: 1,
},
}
if _, err := p.send(p.tr.NewRIRspPacket(pkt.ConnectionID, p.tr.LocalSeq, aurp.RoutingFlagLast, nets)); err != nil {
log.Printf("Couldn't send RI-Rsp packet: %v", err)
}
sstate = ssWaitForRIAck1
case *aurp.RIRspPacket: case *aurp.RIRspPacket:
if rstate != rsWaitForRIRsp { if rstate != rsWaitForRIRsp {
@ -235,8 +246,37 @@ func (p *peer) handle(ctx context.Context) error {
// TODO: Integrate info into route table // TODO: Integrate info into route table
case *aurp.RIAckPacket: case *aurp.RIAckPacket:
// TODO: Continue sending next RI-Rsp (streamed) switch sstate {
// TODO: If SZI flag is set, send ZI-Rsp (transaction) case ssWaitForRIAck1:
// We sent an RI-Rsp, this is the RI-Ack we expected.
case ssWaitForRIAck2:
// We sent an RI-Upd, this is the RI-Ack we expected.
case ssWaitForRIAck3:
// We sent an RD... Why are we here?
continue
default:
log.Printf("Received RI-Ack but was not waiting for one (sender state was %v)", sstate)
}
sstate = ssConnected
// If SZI flag is set, send ZI-Rsp (transaction)
if pkt.Flags&aurp.RoutingFlagSendZoneInfo != 0 {
zones := aurp.ZoneTuples{
{
Network: p.cfg.EtherTalk.NetStart,
Name: p.cfg.EtherTalk.ZoneName,
},
}
if _, err := p.send(p.tr.NewZIRspPacket(zones)); err != nil {
log.Printf("Couldn't send ZI-Rsp packet: %v", err)
}
}
// TODO: Continue sending next RI-Rsp (streamed)?
case *aurp.RIUpdPacket: case *aurp.RIUpdPacket:
// TODO: Integrate info into route table // TODO: Integrate info into route table