64 lines
1.4 KiB
Go
64 lines
1.4 KiB
Go
|
package stun
|
||
|
|
||
|
import "errors"
|
||
|
|
||
|
// UnknownAttributes represents UNKNOWN-ATTRIBUTES attribute.
|
||
|
//
|
||
|
// RFC 5389 Section 15.9
|
||
|
type UnknownAttributes []AttrType
|
||
|
|
||
|
func (a UnknownAttributes) String() string {
|
||
|
s := ""
|
||
|
if len(a) == 0 {
|
||
|
return "<nil>"
|
||
|
}
|
||
|
last := len(a) - 1
|
||
|
for i, t := range a {
|
||
|
s += t.String()
|
||
|
if i != last {
|
||
|
s += ", "
|
||
|
}
|
||
|
}
|
||
|
return s
|
||
|
}
|
||
|
|
||
|
// type size is 16 bit.
|
||
|
const attrTypeSize = 4
|
||
|
|
||
|
// AddTo adds UNKNOWN-ATTRIBUTES attribute to message.
|
||
|
func (a UnknownAttributes) AddTo(m *Message) error {
|
||
|
v := make([]byte, 0, attrTypeSize*20) // 20 should be enough
|
||
|
// If len(a.Types) > 20, there will be allocations.
|
||
|
for i, t := range a {
|
||
|
v = append(v, 0, 0, 0, 0) // 4 times by 0 (16 bits)
|
||
|
first := attrTypeSize * i
|
||
|
last := first + attrTypeSize
|
||
|
bin.PutUint16(v[first:last], t.Value())
|
||
|
}
|
||
|
m.Add(AttrUnknownAttributes, v)
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// ErrBadUnknownAttrsSize means that UNKNOWN-ATTRIBUTES attribute value
|
||
|
// has invalid length.
|
||
|
var ErrBadUnknownAttrsSize = errors.New("bad UNKNOWN-ATTRIBUTES size")
|
||
|
|
||
|
// GetFrom parses UNKNOWN-ATTRIBUTES from message.
|
||
|
func (a *UnknownAttributes) GetFrom(m *Message) error {
|
||
|
v, err := m.Get(AttrUnknownAttributes)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if len(v)%attrTypeSize != 0 {
|
||
|
return ErrBadUnknownAttrsSize
|
||
|
}
|
||
|
*a = (*a)[:0]
|
||
|
first := 0
|
||
|
for first < len(v) {
|
||
|
last := first + attrTypeSize
|
||
|
*a = append(*a, AttrType(bin.Uint16(v[first:last])))
|
||
|
first = last
|
||
|
}
|
||
|
return nil
|
||
|
}
|