Tweak ZI-Rsp

This commit is contained in:
Josh Deprez 2024-04-19 16:48:59 +10:00
parent c8d46cef85
commit 0005f827e5
No known key found for this signature in database
3 changed files with 32 additions and 33 deletions

View file

@ -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,
})
}
}

View file

@ -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

View file

@ -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