99 lines
2.5 KiB
Go
99 lines
2.5 KiB
Go
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,
|
|
}
|
|
}
|