From 0005f827e5e92b46f0657d632838e8e8cc462f4b Mon Sep 17 00:00:00 2001 From: Josh Deprez Date: Fri, 19 Apr 2024 16:48:59 +1000 Subject: [PATCH] Tweak ZI-Rsp --- aurp/transport.go | 26 +++++++++++++++----------- aurp/zone_info.go | 16 +++++++++------- router/peer.go | 23 ++++++++--------------- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/aurp/transport.go b/aurp/transport.go index f3fe5a6..74d103f 100644 --- a/aurp/transport.go +++ b/aurp/transport.go @@ -20,6 +20,8 @@ import ( "encoding/binary" "fmt" "io" + + "github.com/sfiera/multitalk/pkg/ddp" ) // TrHeader represent an AURP-Tr packet header. It includes the domain header. @@ -175,20 +177,22 @@ func (tr *Transport) NewRIAckPacket(connID, seq uint16, szi RoutingFlag) *RIAckP // NewZIRspPacket returns a new ZI-Rsp packet structure containing the given // zone information. It automatically chooses between subcodes 1 or 2 depending // on whether there is one network ID or more than one network ID. -func (tr *Transport) NewZIRspPacket(zones ZoneTuples) *ZIRspPacket { +func (tr *Transport) NewZIRspPacket(zoneLists map[ddp.Network][]string) *ZIRspPacket { // Only one zone: use non-extended subcode := SubcodeZoneInfoNonExt - if len(zones) > 1 { - // Count distinct networks - nns := make(map[uint16]struct{}) - for _, z := range zones { - nns[z.Network] = struct{}{} - } - + if len(zoneLists) == 1 { // Only one network: use extended format - // More than one network: use non-extended - if len(nns) == 1 { - subcode = SubcodeZoneInfoExt + subcode = SubcodeZoneInfoExt + } + + // Translate from network->zones map into zone tuples + var zones ZoneTuples + for nn, zl := range zoneLists { + for _, z := range zl { + zones = append(zones, ZoneTuple{ + Network: nn, + Name: z, + }) } } diff --git a/aurp/zone_info.go b/aurp/zone_info.go index 76017b8..fb83f07 100644 --- a/aurp/zone_info.go +++ b/aurp/zone_info.go @@ -21,6 +21,8 @@ import ( "fmt" "io" "strings" + + "github.com/sfiera/multitalk/pkg/ddp" ) // Subcode is used to distinguish types of zone request/response. @@ -45,7 +47,7 @@ func parseSubcode(p []byte) (Subcode, []byte, error) { type ZIReqPacket struct { Header Subcode - Networks []uint16 + Networks []ddp.Network } func (p *ZIReqPacket) WriteTo(w io.Writer) (int64, error) { @@ -53,7 +55,7 @@ func (p *ZIReqPacket) WriteTo(w io.Writer) (int64, error) { a.writeTo(&p.Header) a.write16(uint16(p.Subcode)) for _, n := range p.Networks { - a.write16(n) + a.write16(uint16(n)) } return a.ret() } @@ -63,9 +65,9 @@ func parseZIReqPacket(p []byte) (*ZIReqPacket, error) { return nil, fmt.Errorf("odd number of bytes %d for networks", len(p)) } c := len(p) / 2 - ns := make([]uint16, 0, c) + ns := make([]ddp.Network, 0, c) for i := range c { - ns[i] = binary.BigEndian.Uint16(p[i*2:][:2]) + ns[i] = ddp.Network(binary.BigEndian.Uint16(p[i*2:][:2])) } return &ZIReqPacket{ Subcode: SubcodeZoneInfoReq, @@ -298,7 +300,7 @@ func (zs ZoneTuples) String() string { } type ZoneTuple struct { - Network uint16 + Network ddp.Network Name string } @@ -317,7 +319,7 @@ func (zs ZoneTuples) WriteTo(w io.Writer) (int64, error) { offsets := make(map[string]uint16) for _, zt := range zs { - a.write16(zt.Network) + a.write16(uint16(zt.Network)) if offset, wrote := offsets[zt.Name]; wrote { // Optimised tuple @@ -351,7 +353,7 @@ func parseZoneTuples(p []byte) (ZoneTuples, error) { return nil, fmt.Errorf("insufficient remaining input length %d for another zone tuple", len(p)) } var zt ZoneTuple - zt.Network = binary.BigEndian.Uint16(p[:2]) + zt.Network = ddp.Network(binary.BigEndian.Uint16(p[:2])) p = p[2:] if nameLen := p[0]; nameLen&0x80 == 0 { // Long tuple diff --git a/router/peer.go b/router/peer.go index 1564b4f..9198016 100644 --- a/router/peer.go +++ b/router/peer.go @@ -339,14 +339,10 @@ func (p *Peer) Handle(ctx context.Context) error { sstate = ssConnected // If SZI flag is set, send ZI-Rsp (transaction) - // TODO: only respond with zones for networks that were in the - // RI-Rsp that corresponded to this RI-Ack + // TODO: split ZI-Rsp packets similarly to ZIP Replies if pkt.Flags&aurp.RoutingFlagSendZoneInfo != 0 { - zones := aurp.ZoneTuples{ - { - Network: uint16(p.Config.EtherTalk.NetStart), - Name: p.Config.EtherTalk.ZoneName, - }, + zones := map[ddp.Network][]string{ + p.Config.EtherTalk.NetStart: {p.Config.EtherTalk.ZoneName}, } if _, err := p.Send(p.Transport.NewZIRspPacket(zones)); err != nil { log.Printf("AURP Peer: Couldn't send ZI-Rsp packet: %v", err) @@ -357,6 +353,9 @@ func (p *Peer) Handle(ctx context.Context) error { case *aurp.RIUpdPacket: // TODO: Integrate info into route table + for _, et := range pkt.Events { + log.Printf("AURP Peer: RI-Upd event %v", et) + } case *aurp.RDPacket: if rstate == rsUnconnected || rstate == rsWaitForOpenRsp { @@ -375,14 +374,8 @@ func (p *Peer) Handle(ctx context.Context) error { rstate = rsUnconnected case *aurp.ZIReqPacket: - // TODO: only respond with zones for networks specified by the - // ZI-Req - zones := aurp.ZoneTuples{ - { - Network: uint16(p.Config.EtherTalk.NetStart), - Name: p.Config.EtherTalk.ZoneName, - }, - } + // TODO: split ZI-Rsp packets similarly to ZIP Replies + zones := p.ZoneTable.Query(pkt.Networks) if _, err := p.Send(p.Transport.NewZIRspPacket(zones)); err != nil { log.Printf("AURP Peer: Couldn't send ZI-Rsp packet: %v", err) return err