Tweak ZI-Rsp
This commit is contained in:
parent
c8d46cef85
commit
0005f827e5
3 changed files with 32 additions and 33 deletions
|
@ -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,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue