diff --git a/aurp/aurp.go b/aurp/aurp.go index d49d83e..0382595 100644 --- a/aurp/aurp.go +++ b/aurp/aurp.go @@ -259,8 +259,10 @@ func (ot *OptionTuple) WriteTo(w io.Writer) (int64, error) { } a := acc(w) - a.write8(uint8(len(ot.Data) + 1)) - a.write8(uint8(ot.Type)) + a.write([]byte{ + byte(len(ot.Data) + 1), + byte(ot.Type), + }) a.write(ot.Data) return a.ret() } @@ -371,6 +373,36 @@ func parseOpenReq(p []byte) (*OpenReqPacket, error) { }, nil } +// OpenRsp is used to respond to Open-Req. +type OpenRspPacket struct { + *Header + + RateOrErrCode int16 + Options Options +} + +func (p *OpenRspPacket) WriteTo(w io.Writer) (int64, error) { + a := acc(w) + a.writeTo(p.Header) + a.write16(uint16(p.RateOrErrCode)) + a.writeTo(p.Options) + return a.ret() +} + +func parseOpenRsp(p []byte) (*OpenRspPacket, error) { + if len(p) < 3 { + return nil, fmt.Errorf("insufficient input length %d for Open-Rsp packet", len(p)) + } + opts, err := parseOptions(p[2:]) + if err != nil { + return nil, err + } + return &OpenRspPacket{ + RateOrErrCode: int16(binary.BigEndian.Uint16(p[:2])), + Options: opts, + }, nil +} + // 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. @@ -419,6 +451,9 @@ func ParsePacket(p []byte) (Packet, error) { } orsp.Header = h return orsp, nil + + default: + return nil, fmt.Errorf("unknown routing packet command code %d", h.CommandCode) } default: diff --git a/aurp/wtacc.go b/aurp/wtacc.go index a42c4de..0bbabd7 100644 --- a/aurp/wtacc.go +++ b/aurp/wtacc.go @@ -1,13 +1,12 @@ package aurp import ( - "encoding/binary" "io" ) // wtacc is a helper for io.WriterTo implementations. -// It sacrifices early returns for a shorter syntax. However, it refuses to -// continue writing to the destination writer after detecting an error. +// It sacrifices early returns for a shorter syntax. However, it won't continue +// writing to the destination writer after detecting an error. type wtacc struct { w io.Writer n int64 @@ -21,25 +20,17 @@ func (a *wtacc) ret() (int64, error) { } func (a *wtacc) write8(x uint8) { - if a.err != nil { - return - } - _, a.err = a.w.Write([]byte{x}) - if a.err != nil { - return - } - a.n++ + a.write([]byte{x}) } func (a *wtacc) write16(x uint16) { - if a.err != nil { - return - } - a.err = binary.Write(a.w, binary.BigEndian, x) - if a.err != nil { - return - } - a.n += 2 + // Could do this with: + // binary.Write(a.w, binary.BigEndian, x) + // - but don't wanna + a.write([]byte{ + byte(x >> 8), + byte(x & 0xff), + }) } func (a *wtacc) write(b []byte) {