This commit is contained in:
Josh Deprez 2024-03-22 14:20:31 +11:00
parent b9660caa3d
commit b43fabc5b6
No known key found for this signature in database
9 changed files with 123 additions and 110 deletions

17
aurp/atalk.go Normal file
View file

@ -0,0 +1,17 @@
package aurp
import "io"
// AppleTalkPacket is for encapsulated AppleTalk traffic.
type AppleTalkPacket struct {
DomainHeader // where PacketTypeAppleTalk
Data []byte
}
func (p *AppleTalkPacket) WriteTo(w io.Writer) (int64, error) {
a := acc(w)
a.writeTo(&p.DomainHeader)
a.write(p.Data)
return a.ret()
}

View file

@ -8,34 +8,6 @@ import (
"io"
)
// TrHeader represent an AURP-Tr packet header. It includes the domain header.
type TrHeader struct {
DomainHeader
ConnectionID uint16
Sequence uint16 // Note: 65535 is succeeded by 1, not 0
}
// WriteTo writes the encoded form of the header to w, including the domain
// header.
func (h *TrHeader) WriteTo(w io.Writer) (int64, error) {
a := acc(w)
a.writeTo(&h.DomainHeader)
a.write16(h.ConnectionID)
a.write16(h.Sequence)
return a.ret()
}
func parseTrHeader(p []byte) (TrHeader, []byte, error) {
if len(p) < 4 {
return TrHeader{}, p, fmt.Errorf("insufficient input length %d for tr header", len(p))
}
return TrHeader{
ConnectionID: binary.BigEndian.Uint16(p[:2]),
Sequence: binary.BigEndian.Uint16(p[2:4]),
}, p[4:], nil
}
// Header represents an AURP packet header. It includes the AURP-Tr header,
// which includes the domain header.
type Header struct {
@ -86,16 +58,19 @@ const (
type RoutingFlag uint16
const (
// Open-Req and RI-Req
// Open-Req and RI-Req (SUI flags)
RoutingFlagSUINA RoutingFlag = 0x4000
RoutingFlagSUINDOrNRC RoutingFlag = 0x2000
RoutingFlagSUINDC RoutingFlag = 0x1000
RoutingFlagSUIZC RoutingFlag = 0x0800
// The combination of the above four flags (the SUI flags).
RoutingFlagAllSUI RoutingFlag = 0x7800
// RI-Rsp and GDZL-Rsp
RoutingFlagLast RoutingFlag = 0x8000
// Open-Rsp
// Open-Rsp (environment flags)
RoutingFlagRemappingActive RoutingFlag = 0x4000
RoutingFlagHopCountReduction RoutingFlag = 0x2000
RoutingFlagReservedEnv RoutingFlag = 0x1800
@ -110,20 +85,6 @@ type Packet interface {
io.WriterTo
}
// AppleTalkPacket is for encapsulated AppleTalk traffic.
type AppleTalkPacket struct {
DomainHeader // where PacketTypeAppleTalk
Data []byte
}
func (p *AppleTalkPacket) WriteTo(w io.Writer) (int64, error) {
a := acc(w)
a.writeTo(&p.DomainHeader)
a.write(p.Data)
return a.ret()
}
// ParsePacket parses the body of a UDP packet for a domain header, and then
// based on the packet type, an AURP-Tr header, an AURP routing header, and
// then a particular packet type.

View file

@ -12,8 +12,8 @@ import (
type DomainHeader struct {
DestinationDI DomainIdentifier
SourceDI DomainIdentifier
Version uint16 // Should always be 0x0001
Reserved uint16
Version uint16 // Should always be 0x0001
Reserved uint16 // Should always be 0x0000
PacketType PacketType // 2 = AppleTalk data packet, 3 = AURP packet
}

View file

@ -15,9 +15,6 @@ type OpenReqPacket struct {
}
func (p *OpenReqPacket) WriteTo(w io.Writer) (int64, error) {
p.Sequence = 0
p.CommandCode = CmdCodeOpenReq
a := acc(w)
a.writeTo(&p.Header)
a.write16(p.Version)
@ -48,9 +45,6 @@ type OpenRspPacket struct {
}
func (p *OpenRspPacket) WriteTo(w io.Writer) (int64, error) {
p.Sequence = 0
p.CommandCode = CmdCodeOpenRsp
a := acc(w)
a.writeTo(&p.Header)
a.write16(uint16(p.RateOrErrCode))

View file

@ -13,8 +13,6 @@ type RDPacket struct {
}
func (p *RDPacket) WriteTo(w io.Writer) (int64, error) {
p.CommandCode = CmdCodeRD
a := acc(w)
a.writeTo(&p.Header)
a.write16(uint16(p.ErrorCode))

View file

@ -10,12 +10,6 @@ type RIReqPacket struct {
Header
}
func (p *RIReqPacket) WriteTo(w io.Writer) (int64, error) {
p.Sequence = 0
p.CommandCode = CmdCodeRIReq
return p.Header.WriteTo(w)
}
type RIRspPacket struct {
Header
@ -23,8 +17,6 @@ type RIRspPacket struct {
}
func (p *RIRspPacket) WriteTo(w io.Writer) (int64, error) {
p.CommandCode = CmdCodeRIRsp
a := acc(w)
a.writeTo(&p.Header)
a.writeTo(p.Networks)
@ -45,11 +37,6 @@ type RIAckPacket struct {
Header
}
func (p *RIAckPacket) WriteTo(w io.Writer) (int64, error) {
p.CommandCode = CmdCodeRIAck
return p.Header.WriteTo(w)
}
type RIUpdPacket struct {
Header
@ -57,8 +44,6 @@ type RIUpdPacket struct {
}
func (p *RIUpdPacket) WriteTo(w io.Writer) (int64, error) {
p.CommandCode = CmdCodeRIUpd
a := acc(w)
a.writeTo(&p.Header)
a.writeTo(p.Events)

View file

@ -1,25 +1,9 @@
package aurp
import "io"
type TicklePacket struct {
Header
}
func (p *TicklePacket) WriteTo(w io.Writer) (int64, error) {
p.Sequence = 0
p.CommandCode = CmdCodeTickle
p.Flags = 0
return p.Header.WriteTo(w)
}
type TickleAckPacket struct {
Header
}
func (p *TickleAckPacket) WriteTo(w io.Writer) (int64, error) {
p.Sequence = 0
p.CommandCode = CmdCodeTickleAck
p.Flags = 0
return p.Header.WriteTo(w)
}

99
aurp/transport.go Normal file
View file

@ -0,0 +1,99 @@
package aurp
import (
"encoding/binary"
"fmt"
"io"
)
// TrHeader represent an AURP-Tr packet header. It includes the domain header.
type TrHeader struct {
DomainHeader
ConnectionID uint16
Sequence uint16
}
// WriteTo writes the encoded form of the header to w, including the domain
// header.
func (h *TrHeader) WriteTo(w io.Writer) (int64, error) {
a := acc(w)
a.writeTo(&h.DomainHeader)
a.write16(h.ConnectionID)
a.write16(h.Sequence)
return a.ret()
}
func parseTrHeader(p []byte) (TrHeader, []byte, error) {
if len(p) < 4 {
return TrHeader{}, p, fmt.Errorf("insufficient input length %d for tr header", len(p))
}
return TrHeader{
ConnectionID: binary.BigEndian.Uint16(p[:2]),
Sequence: binary.BigEndian.Uint16(p[2:4]),
}, p[4:], nil
}
// incSequence increments the sequence number.
// Note that 0 is special and 65535+1 = 1, according to AURP.
func (tr *TrHeader) incSequence() {
tr.Sequence++
if tr.Sequence == 0 {
tr.Sequence = 1
}
}
// transaction returns a new TrHeader based on this one, usable for transaction
// requests or responses.
func (tr *TrHeader) transaction() TrHeader {
return TrHeader{
DomainHeader: DomainHeader{
DestinationDI: tr.DestinationDI,
SourceDI: tr.SourceDI,
Version: 1,
Reserved: 0,
PacketType: PacketTypeRouting,
},
ConnectionID: tr.ConnectionID,
Sequence: 0, // Transaction packets all use sequence number 0.
}
}
// DataSender is used to track sender state in a one-way AURP connection.
// Note that both data senders and data recievers can send packets.
type DataSender struct {
TrHeader
}
// NewOpenRspPacket returns a new Open-Rsp packet structure.
func (ds *DataSender) NewOpenRspPacket(envFlags RoutingFlag, rateOrErr int16, opts Options) *OpenRspPacket {
return &OpenRspPacket{
Header: Header{
TrHeader: ds.transaction(),
CommandCode: CmdCodeOpenRsp,
Flags: envFlags,
},
RateOrErrCode: rateOrErr,
Options: opts,
}
}
// DataReceiver is used to track reciever state in a one-way AURP connection.
// Note that both data senders and data recievers can send packets.
type DataReceiver struct {
TrHeader
}
// NewOpenReqPacket returns a new Open-Req packet structure. By default it sets
// all SUI flags and uses version 1.
func (dr *DataReceiver) NewOpenReqPacket(opts Options) *OpenReqPacket {
return &OpenReqPacket{
Header: Header{
TrHeader: dr.transaction(),
CommandCode: CmdCodeOpenReq,
Flags: RoutingFlagAllSUI,
},
Version: 1,
Options: opts,
}
}

View file

@ -32,11 +32,6 @@ type ZIReqPacket struct {
}
func (p *ZIReqPacket) WriteTo(w io.Writer) (int64, error) {
p.Sequence = 0
p.CommandCode = CmdCodeZoneReq
p.Flags = 0
p.Subcode = SubcodeZoneInfoReq
a := acc(w)
a.writeTo(&p.Header)
a.write16(uint16(p.Subcode))
@ -79,11 +74,6 @@ type ZIRspPacket struct {
}
func (p *ZIRspPacket) WriteTo(w io.Writer) (int64, error) {
p.Sequence = 0
p.CommandCode = CmdCodeZoneRsp
p.Flags = 0
// Subcode can vary for this packet type: it's either 1 or 2
a := acc(w)
a.writeTo(&p.Header)
a.write16(uint16(p.Subcode))
@ -109,11 +99,6 @@ type GDZLReqPacket struct {
}
func (p *GDZLReqPacket) WriteTo(w io.Writer) (int64, error) {
p.Sequence = 0
p.CommandCode = CmdCodeZoneReq
p.Flags = 0
p.Subcode = SubcodeGetDomainZoneList
a := acc(w)
a.writeTo(&p.Header)
a.write16(uint16(p.Subcode))
@ -145,11 +130,6 @@ func (p *GDZLRspPacket) WriteTo(w io.Writer) (int64, error) {
}
}
p.Sequence = 0
p.CommandCode = CmdCodeZoneRsp
// Flags is used to distinguish the final response packet, so leave alone
p.Subcode = SubcodeGetDomainZoneList
a := acc(w)
a.writeTo(&p.Header)
a.write16(uint16(p.Subcode))
@ -207,11 +187,6 @@ func (p *GZNReqPacket) WriteTo(w io.Writer) (int64, error) {
return 0, fmt.Errorf("zone name %q too long", p.ZoneName)
}
p.Sequence = 0
p.CommandCode = CmdCodeZoneReq
p.Flags = 0
p.Subcode = SubcodeGetZonesNet
a := acc(w)
a.writeTo(&p.Header)
a.write16(uint16(p.Subcode))