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" "encoding/binary"
"fmt" "fmt"
"io" "io"
"github.com/sfiera/multitalk/pkg/ddp"
) )
// TrHeader represent an AURP-Tr packet header. It includes the domain header. // 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 // NewZIRspPacket returns a new ZI-Rsp packet structure containing the given
// zone information. It automatically chooses between subcodes 1 or 2 depending // zone information. It automatically chooses between subcodes 1 or 2 depending
// on whether there is one network ID or more than one network ID. // 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 // Only one zone: use non-extended
subcode := SubcodeZoneInfoNonExt subcode := SubcodeZoneInfoNonExt
if len(zones) > 1 { if len(zoneLists) == 1 {
// Count distinct networks // Only one network: use extended format
nns := make(map[uint16]struct{}) subcode = SubcodeZoneInfoExt
for _, z := range zones {
nns[z.Network] = struct{}{}
} }
// Only one network: use extended format // Translate from network->zones map into zone tuples
// More than one network: use non-extended var zones ZoneTuples
if len(nns) == 1 { for nn, zl := range zoneLists {
subcode = SubcodeZoneInfoExt for _, z := range zl {
zones = append(zones, ZoneTuple{
Network: nn,
Name: z,
})
} }
} }

View file

@ -21,6 +21,8 @@ import (
"fmt" "fmt"
"io" "io"
"strings" "strings"
"github.com/sfiera/multitalk/pkg/ddp"
) )
// Subcode is used to distinguish types of zone request/response. // Subcode is used to distinguish types of zone request/response.
@ -45,7 +47,7 @@ func parseSubcode(p []byte) (Subcode, []byte, error) {
type ZIReqPacket struct { type ZIReqPacket struct {
Header Header
Subcode Subcode
Networks []uint16 Networks []ddp.Network
} }
func (p *ZIReqPacket) WriteTo(w io.Writer) (int64, error) { 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.writeTo(&p.Header)
a.write16(uint16(p.Subcode)) a.write16(uint16(p.Subcode))
for _, n := range p.Networks { for _, n := range p.Networks {
a.write16(n) a.write16(uint16(n))
} }
return a.ret() 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)) return nil, fmt.Errorf("odd number of bytes %d for networks", len(p))
} }
c := len(p) / 2 c := len(p) / 2
ns := make([]uint16, 0, c) ns := make([]ddp.Network, 0, c)
for i := range 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{ return &ZIReqPacket{
Subcode: SubcodeZoneInfoReq, Subcode: SubcodeZoneInfoReq,
@ -298,7 +300,7 @@ func (zs ZoneTuples) String() string {
} }
type ZoneTuple struct { type ZoneTuple struct {
Network uint16 Network ddp.Network
Name string Name string
} }
@ -317,7 +319,7 @@ func (zs ZoneTuples) WriteTo(w io.Writer) (int64, error) {
offsets := make(map[string]uint16) offsets := make(map[string]uint16)
for _, zt := range zs { for _, zt := range zs {
a.write16(zt.Network) a.write16(uint16(zt.Network))
if offset, wrote := offsets[zt.Name]; wrote { if offset, wrote := offsets[zt.Name]; wrote {
// Optimised tuple // 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)) return nil, fmt.Errorf("insufficient remaining input length %d for another zone tuple", len(p))
} }
var zt ZoneTuple var zt ZoneTuple
zt.Network = binary.BigEndian.Uint16(p[:2]) zt.Network = ddp.Network(binary.BigEndian.Uint16(p[:2]))
p = p[2:] p = p[2:]
if nameLen := p[0]; nameLen&0x80 == 0 { if nameLen := p[0]; nameLen&0x80 == 0 {
// Long tuple // Long tuple

View file

@ -339,14 +339,10 @@ func (p *Peer) Handle(ctx context.Context) error {
sstate = ssConnected sstate = ssConnected
// If SZI flag is set, send ZI-Rsp (transaction) // If SZI flag is set, send ZI-Rsp (transaction)
// TODO: only respond with zones for networks that were in the // TODO: split ZI-Rsp packets similarly to ZIP Replies
// RI-Rsp that corresponded to this RI-Ack
if pkt.Flags&aurp.RoutingFlagSendZoneInfo != 0 { if pkt.Flags&aurp.RoutingFlagSendZoneInfo != 0 {
zones := aurp.ZoneTuples{ zones := map[ddp.Network][]string{
{ p.Config.EtherTalk.NetStart: {p.Config.EtherTalk.ZoneName},
Network: uint16(p.Config.EtherTalk.NetStart),
Name: p.Config.EtherTalk.ZoneName,
},
} }
if _, err := p.Send(p.Transport.NewZIRspPacket(zones)); err != nil { if _, err := p.Send(p.Transport.NewZIRspPacket(zones)); err != nil {
log.Printf("AURP Peer: Couldn't send ZI-Rsp packet: %v", err) 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: case *aurp.RIUpdPacket:
// TODO: Integrate info into route table // TODO: Integrate info into route table
for _, et := range pkt.Events {
log.Printf("AURP Peer: RI-Upd event %v", et)
}
case *aurp.RDPacket: case *aurp.RDPacket:
if rstate == rsUnconnected || rstate == rsWaitForOpenRsp { if rstate == rsUnconnected || rstate == rsWaitForOpenRsp {
@ -375,14 +374,8 @@ func (p *Peer) Handle(ctx context.Context) error {
rstate = rsUnconnected rstate = rsUnconnected
case *aurp.ZIReqPacket: case *aurp.ZIReqPacket:
// TODO: only respond with zones for networks specified by the // TODO: split ZI-Rsp packets similarly to ZIP Replies
// ZI-Req zones := p.ZoneTable.Query(pkt.Networks)
zones := aurp.ZoneTuples{
{
Network: uint16(p.Config.EtherTalk.NetStart),
Name: p.Config.EtherTalk.ZoneName,
},
}
if _, err := p.Send(p.Transport.NewZIRspPacket(zones)); err != nil { if _, err := p.Send(p.Transport.NewZIRspPacket(zones)); err != nil {
log.Printf("AURP Peer: Couldn't send ZI-Rsp packet: %v", err) log.Printf("AURP Peer: Couldn't send ZI-Rsp packet: %v", err)
return err return err