Documentation ¶
Overview ¶
Package stun implements Session Traversal Utilities for NAT (STUN) RFC 5389.
The stun package is intended to use by package that implements extension to STUN (e.g. TURN) or client/server applications.
Most methods are designed to be zero allocations. If it is not enough, low-level methods are available. On other hand, there are helpers that reduce code repeat.
See examples for Message for basic usage, or https://github.com/pion/turn package for example of stun extension implementation.
Index ¶
- Constants
- Variables
- func CheckOverflow(_ AttrType, got, max int) error
- func CheckSize(_ AttrType, got, expected int) error
- func Decode(data []byte, m *Message) error
- func FingerprintValue(b []byte) uint32
- func IsAttrSizeInvalid(err error) bool
- func IsAttrSizeOverflow(err error) bool
- func IsMessage(b []byte) bool
- func NewTransactionID() (b [TransactionIDSize]byte)
- func WithNoRetransmit(c *Client)
- type Agent
- func (a *Agent) Close() error
- func (a *Agent) Collect(gcTime time.Time) error
- func (a *Agent) Process(m *Message) error
- func (a *Agent) SetHandler(h Handler) error
- func (a *Agent) Start(id [TransactionIDSize]byte, deadline time.Time) error
- func (a *Agent) Stop(id [TransactionIDSize]byte) error
- func (a *Agent) StopWithError(id [TransactionIDSize]byte, err error) error
- type AlternateServer
- type AttrType
- type Attributes
- type Checker
- type Client
- type ClientAgent
- type ClientOption
- func WithAgent(a ClientAgent) ClientOption
- func WithClock(clock Clock) ClientOption
- func WithCollector(coll Collector) ClientOption
- func WithHandler(h Handler) ClientOption
- func WithNoConnClose() ClientOption
- func WithRTO(rto time.Duration) ClientOption
- func WithTimeoutRate(d time.Duration) ClientOption
- type Clock
- type CloseErr
- type Collector
- type Connection
- type DecodeErr
- type DecodeErrPlace
- type DialConfig
- type ErrorCode
- type ErrorCodeAttribute
- type Event
- type FingerprintAttr
- type Getter
- type Handler
- type MappedAddress
- type Message
- func (m *Message) Add(t AttrType, v []byte)
- func (m *Message) AddTo(b *Message) error
- func (m *Message) Build(setters ...Setter) error
- func (m *Message) Check(checkers ...Checker) error
- func (m *Message) CloneTo(b *Message) error
- func (m *Message) Contains(t AttrType) bool
- func (m *Message) Decode() error
- func (m *Message) Encode()
- func (m *Message) Equal(b *Message) bool
- func (m *Message) ForEach(t AttrType, f func(m *Message) error) error
- func (m *Message) Get(t AttrType) ([]byte, error)
- func (m *Message) GobDecode(data []byte) error
- func (m Message) GobEncode() ([]byte, error)
- func (m Message) MarshalBinary() (data []byte, err error)
- func (m *Message) NewTransactionID() error
- func (m *Message) Parse(getters ...Getter) error
- func (m *Message) ReadFrom(r io.Reader) (int64, error)
- func (m *Message) Reset()
- func (m *Message) SetType(t MessageType)
- func (m *Message) String() string
- func (m *Message) UnmarshalBinary(data []byte) error
- func (m *Message) Write(tBuf []byte) (int, error)
- func (m *Message) WriteAttributes()
- func (m *Message) WriteHeader()
- func (m *Message) WriteLength()
- func (m *Message) WriteTo(w io.Writer) (int64, error)
- func (m *Message) WriteTransactionID()
- func (m *Message) WriteType()
- type MessageClass
- type MessageIntegrity
- type MessageType
- type Method
- type Nonce
- type OtherAddress
- type ProtoType
- type RawAttribute
- type Realm
- type ResponseOrigin
- type SchemeType
- type Setter
- type Software
- type StopErr
- type TextAttribute
- type URI
- type UnknownAttributes
- type Username
- type XORMappedAddress
Examples ¶
Constants ¶
const ( DefaultPort = 3478 DefaultTLSPort = 5349 )
IANA assigned ports for "stun" protocol.
const ( CodeUnauthorized )CodeUnauthorised =
DEPRECATED constants.
const ( // TransactionIDSize is length of transaction id array (in bytes). TransactionIDSize = 12 // 96 bit )
Variables ¶
var ( // ErrTransactionStopped indicates that transaction was manually stopped. ErrTransactionStopped = errors.New("transaction is stopped") // ErrTransactionNotExists indicates that agent failed to find transaction. ErrTransactionNotExists = errors.New("transaction not exists") // ErrTransactionExists indicates that transaction with same id is already // registered. ErrTransactionExists = errors.New("transaction exists with same id") )
var ( // Binding request message type. BindingRequest = NewType(MethodBinding, ClassRequest) //nolint:gochecknoglobals // Binding success response message type BindingSuccess = NewType(MethodBinding, ClassSuccessResponse) //nolint:gochecknoglobals // Binding error response message type. BindingError = NewType(MethodBinding, ClassErrorResponse) //nolint:gochecknoglobals )
Common STUN message types.
var ( // ErrUnknownType indicates an error with Unknown info. ErrUnknownType = errors.New("Unknown") // ErrSchemeType indicates the scheme type could not be parsed. ErrSchemeType = errors.New("unknown scheme type") // ErrSTUNQuery indicates query arguments are provided in a STUN URL. ErrSTUNQuery = errors.New("queries not supported in stun address") // ErrInvalidQuery indicates an malformed query is provided. ErrInvalidQuery = errors.New("invalid query") // ErrHost indicates malformed hostname is provided. ErrHost = errors.New("invalid hostname") // ErrPort indicates malformed port is provided. ErrPort = errors.New("invalid port") // ErrProtoType indicates an unsupported transport type was provided. ErrProtoType = errors.New("invalid transport protocol type") )
var ErrAgentClosed = errors.New("agent is closed")
ErrAgentClosed indicates that agent is in closed state and is unable to handle transactions.
var ErrAttributeNotFound = errors.New("attribute not found")
ErrAttributeNotFound means that attribute with provided attribute type does not exist in message.
var ErrAttributeSizeInvalid = errors.New("attribute size is invalid")
ErrAttributeSizeInvalid means that decoded attribute size is invalid.
var ErrAttributeSizeOverflow = errors.New("attribute size overflow")
ErrAttributeSizeOverflow means that decoded attribute size is too big.
var ErrBadIPLength = errors.New("invalid length of IP value")
ErrBadIPLength means that len(IP) is not net.{IPv6len,IPv4len}.
var ErrBadUnknownAttrsSize = errors.New("bad UNKNOWN-ATTRIBUTES size")
ErrBadUnknownAttrsSize means that UNKNOWN-ATTRIBUTES attribute value has invalid length.
var ErrClientClosed = errors.New("client is closed")
ErrClientClosed indicates that client is closed.
var ErrClientNotInitialized = errors.New("client not initialized")
ErrClientNotInitialized means that client connection or agent is nil.
var ErrDecodeToNil = errors.New("attempt to decode to nil message")
ErrDecodeToNil occurs on Decode(data, nil) call.
var ErrFingerprintBeforeIntegrity = errors.New("FINGERPRINT before MESSAGE-INTEGRITY attribute")
ErrFingerprintBeforeIntegrity means that FINGERPRINT attribute is already in message, so MESSAGE-INTEGRITY attribute cannot be added.
var ErrFingerprintMismatch = errors.New("fingerprint check failed")
ErrFingerprintMismatch means that computed fingerprint differs from expected.
var ErrIntegrityMismatch = errors.New("integrity check failed")
ErrIntegrityMismatch means that computed HMAC differs from expected.
var ErrNoConnection = errors.New("no connection provided")
ErrNoConnection means that ClientOptions.Connection is nil.
var ErrNoDefaultReason = errors.New("no default reason for ErrorCode")
ErrNoDefaultReason means that default reason for provided error code is not defined in RFC.
var ErrTransactionTimeOut = errors.New("transaction is timed out")
ErrTransactionTimeOut indicates that transaction has reached deadline.
var ErrUnexpectedHeaderEOF = errors.New("unexpected EOF: not enough bytes to read header")
ErrUnexpectedHeaderEOF means that there were not enough bytes in m.Raw to read header.
var ErrUnsupportedURI = fmt.Errorf("invalid schema or transport")
ErrUnsupportedURI is an error thrown if the user passes an unsupported STUN or TURN URI
Functions ¶
func CheckOverflow ¶ added in v0.3.0
CheckOverflow returns ErrAttributeSizeOverflow if got is bigger that max.
func CheckSize ¶ added in v0.3.0
CheckSize returns ErrAttrSizeInvalid if got is not equal to expected.
func FingerprintValue ¶ added in v0.3.0
FingerprintValue returns CRC-32 of b XOR-ed by 0x5354554e.
The value of the attribute is computed as the CRC-32 of the STUN message up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with the 32-bit value 0x5354554e (the XOR helps in cases where an application packet is also using CRC-32 in it).
func IsAttrSizeInvalid ¶ added in v0.3.0
IsAttrSizeInvalid returns true if error means that attribute size is invalid.
func IsAttrSizeOverflow ¶ added in v0.3.0
IsAttrSizeOverflow returns true if error means that attribute size is too big.
func IsMessage ¶ added in v0.3.0
IsMessage returns true if b looks like STUN message. Useful for multiplexing. IsMessage does not guarantee that decoding will be successful.
func NewTransactionID ¶ added in v0.3.0
func NewTransactionID() (b [TransactionIDSize]byte)
NewTransactionID returns new random transaction ID using crypto/rand as source.
func WithNoRetransmit ¶ added in v0.3.0
func WithNoRetransmit(c *Client)
WithNoRetransmit disables retransmissions and sets RTO to defaultMaxAttempts * defaultRTO which will be effectively time out if not set.
Useful for TCP connections where transport handles RTO.
Types ¶
type Agent ¶ added in v0.3.0
type Agent struct {
// contains filtered or unexported fields
}
Agent is low-level abstraction over transaction list that handles concurrency (all calls are goroutine-safe) and time outs (via Collect call).
func NewAgent ¶ added in v0.3.0
NewAgent initializes and returns new Agent with provided handler. If h is nil, the NoopHandler will be used.
func (*Agent) Close ¶ added in v0.3.0
Close terminates all transactions with ErrAgentClosed and renders Agent to closed state.
func (*Agent) Collect ¶ added in v0.3.0
Collect terminates all transactions that have deadline before provided time, blocking until all handlers will process ErrTransactionTimeOut. Will return ErrAgentClosed if agent is already closed.
It is safe to call Collect concurrently but makes no sense.
func (*Agent) Process ¶ added in v0.3.0
Process incoming message, synchronously passing it to handler.
func (*Agent) SetHandler ¶ added in v0.3.0
SetHandler sets agent handler to h.
func (*Agent) Start ¶ added in v0.3.0
Start registers transaction with provided id and deadline. Could return ErrAgentClosed, ErrTransactionExists.
Agent handler is guaranteed to be eventually called.
func (*Agent) Stop ¶ added in v0.3.0
func (a *Agent) Stop(id [TransactionIDSize]byte) error
Stop stops transaction by id with ErrTransactionStopped, blocking until handler returns.
func (*Agent) StopWithError ¶ added in v0.3.0
func (a *Agent) StopWithError(id [TransactionIDSize]byte, err error) error
StopWithError removes transaction from list and calls handler with provided error. Can return ErrTransactionNotExists and ErrAgentClosed.
type AlternateServer ¶ added in v0.3.0
AlternateServer represents ALTERNATE-SERVER attribute.
func (*AlternateServer) AddTo ¶ added in v0.3.0
func (s *AlternateServer) AddTo(m *Message) error
AddTo adds ALTERNATE-SERVER attribute to message.
func (*AlternateServer) GetFrom ¶ added in v0.3.0
func (s *AlternateServer) GetFrom(m *Message) error
GetFrom decodes ALTERNATE-SERVER from message.
type AttrType ¶
type AttrType uint16
AttrType is attribute type.
const ( AttrMappedAddress AttrType = 0x0001 // MAPPED-ADDRESS AttrUsername AttrType = 0x0006 // USERNAME AttrMessageIntegrity AttrType = 0x0008 // MESSAGE-INTEGRITY AttrErrorCode AttrType = 0x0009 // ERROR-CODE AttrUnknownAttributes AttrType = 0x000A // UNKNOWN-ATTRIBUTES AttrRealm AttrType = 0x0014 // REALM AttrNonce AttrType = 0x0015 // NONCE AttrXORMappedAddress AttrType = 0x0020 // XOR-MAPPED-ADDRESS )
Attributes from comprehension-required range (0x0000-0x7FFF).
const ( AttrSoftware AttrType = 0x8022 // SOFTWARE AttrAlternateServer AttrType = 0x8023 // ALTERNATE-SERVER AttrFingerprint AttrType = 0x8028 // FINGERPRINT )
Attributes from comprehension-optional range (0x8000-0xFFFF).
const ( AttrPriority AttrType = 0x0024 // PRIORITY AttrUseCandidate AttrType = 0x0025 // USE-CANDIDATE AttrICEControlled AttrType = 0x8029 // ICE-CONTROLLED AttrICEControlling AttrType = 0x802A // ICE-CONTROLLING )
Attributes from RFC 5245 ICE.
const ( AttrChannelNumber AttrType = 0x000C // CHANNEL-NUMBER AttrLifetime AttrType = 0x000D // LIFETIME AttrXORPeerAddress AttrType = 0x0012 // XOR-PEER-ADDRESS AttrData AttrType = 0x0013 // DATA AttrXORRelayedAddress AttrType = 0x0016 // XOR-RELAYED-ADDRESS AttrEvenPort AttrType = 0x0018 // EVEN-PORT AttrRequestedTransport AttrType = 0x0019 // REQUESTED-TRANSPORT AttrDontFragment AttrType = 0x001A // DONT-FRAGMENT AttrReservationToken AttrType = 0x0022 // RESERVATION-TOKEN )
Attributes from RFC 5766 TURN.
const ( AttrChangeRequest AttrType = 0x0003 // CHANGE-REQUEST AttrPadding AttrType = 0x0026 // PADDING AttrResponsePort AttrType = 0x0027 // RESPONSE-PORT AttrCacheTimeout AttrType = 0x8027 // CACHE-TIMEOUT AttrResponseOrigin AttrType = 0x802b // RESPONSE-ORIGIN AttrOtherAddress AttrType = 0x802C // OTHER-ADDRESS )
Attributes from RFC 5780 NAT Behavior Discovery
const ( AttrSourceAddress AttrType = 0x0004 // SOURCE-ADDRESS AttrChangedAddress AttrType = 0x0005 // CHANGED-ADDRESS )
Attributes from RFC 3489, removed by RFC 5389,
but still used by RFC5389-implementing software like Vovida.org, reTURNServer, etc.
const ( AttrMessageIntegritySHA256 AttrType = 0x001C // MESSAGE-INTEGRITY-SHA256 AttrPasswordAlgorithm AttrType = 0x001D // PASSWORD-ALGORITHM AttrUserhash AttrType = 0x001E // USERHASH AttrPasswordAlgorithms AttrType = 0x8002 // PASSWORD-ALGORITHMS AttrAlternateDomain AttrType = 0x8003 // ALTERNATE-DOMAIN )
Attributes from RFC 8489 STUN.
const (
AttrConnectionID AttrType = 0x002a // CONNECTION-ID
)
Attributes from RFC 6062 TURN Extensions for TCP Allocations.
const (
AttrOrigin AttrType = 0x802F
)
Attributes from An Origin Attribute for the STUN Protocol.
const (
AttrRequestedAddressFamily AttrType = 0x0017 // REQUESTED-ADDRESS-FAMILY
)
Attributes from RFC 6156 TURN IPv6.
func (AttrType) Optional ¶ added in v0.3.0
Optional returns true if type is from comprehension-optional range (0x8000-0xFFFF).
type Attributes ¶ added in v0.3.0
type Attributes []RawAttribute
Attributes is list of message attributes.
func (Attributes) Get ¶ added in v0.3.0
func (a Attributes) Get(t AttrType) (RawAttribute, bool)
Get returns first attribute from list by the type. If attribute is present the RawAttribute is returned and the boolean is true. Otherwise the returned RawAttribute will be empty and boolean will be false.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client simulates "connection" to STUN server.
func Dial ¶ added in v0.3.0
Dial connects to the address on the named network and then initializes Client on that connection, returning error if any.
func DialURI ¶ added in v0.6.0
func DialURI(uri *URI, cfg *DialConfig) (*Client, error)
DialURI connect to the STUN/TURN URI and then initializes Client on that connection, returning error if any.
func NewClient ¶
func NewClient(conn Connection, options ...ClientOption) (*Client, error)
NewClient initializes new Client from provided options, starting internal goroutines and using default options fields if necessary. Call Close method after using Client to close conn and release resources.
The conn will be closed on Close call. Use WithNoConnClose option to prevent that.
Note that user should handle the protocol multiplexing, client does not provide any API for it, so if you need to read application data, wrap the connection with your (de-)multiplexer and pass the wrapper as conn.
func (*Client) Do ¶ added in v0.3.0
Do is Start wrapper that waits until callback is called. If no callback provided, Indicate is called instead.
Do has cpu overhead due to blocking, see BenchmarkClient_Do. Use Start method for less overhead.
func (*Client) Indicate ¶ added in v0.3.0
Indicate sends indication m to server. Shorthand to Start call with zero deadline and callback.
type ClientAgent ¶ added in v0.3.0
type ClientAgent interface { Process(*Message) error Close() error Start(id [TransactionIDSize]byte, deadline time.Time) error Stop(id [TransactionIDSize]byte) error Collect(time.Time) error SetHandler(h Handler) error }
ClientAgent is Agent implementation that is used by Client to process transactions.
type ClientOption ¶ added in v0.3.0
type ClientOption func(c *Client)
ClientOption sets some client option.
func WithAgent ¶ added in v0.3.0
func WithAgent(a ClientAgent) ClientOption
WithAgent sets client STUN agent.
Defaults to agent implementation in current package, see agent.go.
func WithClock ¶ added in v0.3.0
func WithClock(clock Clock) ClientOption
WithClock sets Clock of client, the source of current time. Also clock is passed to default collector if set.
func WithCollector ¶ added in v0.3.0
func WithCollector(coll Collector) ClientOption
WithCollector rests client timeout collector, the implementation of ticker which calls function on each tick.
func WithHandler ¶ added in v0.3.0
func WithHandler(h Handler) ClientOption
WithHandler sets client handler which is called if Agent emits the Event with TransactionID that is not currently registered by Client. Useful for handling Data indications from TURN server.
func WithNoConnClose ¶ added in v0.3.0
func WithNoConnClose() ClientOption
WithNoConnClose prevents client from closing underlying connection when the Close() method is called.
func WithRTO ¶ added in v0.3.0
func WithRTO(rto time.Duration) ClientOption
WithRTO sets client RTO as defined in STUN RFC.
func WithTimeoutRate ¶ added in v0.3.0
func WithTimeoutRate(d time.Duration) ClientOption
WithTimeoutRate sets RTO timer minimum resolution.
type Collector ¶ added in v0.3.0
Collector calls function f with constant rate.
The simple Collector is ticker which calls function on each tick.
type Connection ¶ added in v0.3.0
Connection wraps Reader, Writer and Closer interfaces.
type DecodeErr ¶ added in v0.3.0
type DecodeErr struct { Place DecodeErrPlace Message string }
DecodeErr records an error and place when it is occurred.
func (DecodeErr) IsInvalidCookie ¶ added in v0.3.0
IsInvalidCookie returns true if error means that magic cookie value is invalid.
func (DecodeErr) IsPlace ¶ added in v0.3.0
func (e DecodeErr) IsPlace(p DecodeErrPlace) bool
IsPlace reports if error place is p.
func (DecodeErr) IsPlaceChildren ¶ added in v0.3.0
IsPlaceChildren reports if error place children is c.
func (DecodeErr) IsPlaceParent ¶ added in v0.3.0
IsPlaceParent reports if error place parent is p.
type DecodeErrPlace ¶ added in v0.3.0
DecodeErrPlace records a place where error is occurred.
func (DecodeErrPlace) String ¶ added in v0.3.0
func (p DecodeErrPlace) String() string
type DialConfig ¶ added in v0.6.0
DialConfig is used to pass configuration to DialURI()
type ErrorCode ¶
type ErrorCode int
ErrorCode is code for ERROR-CODE attribute.
const ( CodeTryAlternate ErrorCode = 300 CodeBadRequest ErrorCode = 400 CodeUnknownAttribute ErrorCode = 420 CodeStaleNonce ErrorCode = 438 CodeRoleConflict ErrorCode = 487 CodeServerError ErrorCode = 500 )
Possible error codes.
const ( CodeForbidden ErrorCode = 403 // Forbidden CodeAllocMismatch ErrorCode = 437 // Allocation Mismatch CodeWrongCredentials ErrorCode = 441 // Wrong Credentials CodeUnsupportedTransProto ErrorCode = 442 // Unsupported Transport Protocol CodeAllocQuotaReached ErrorCode = 486 // Allocation Quota Reached CodeInsufficientCapacity ErrorCode = 508 // Insufficient Capacity )
Error codes from RFC 5766.
Error codes from RFC 6062.
type ErrorCodeAttribute ¶ added in v0.3.0
ErrorCodeAttribute represents ERROR-CODE attribute.
func (ErrorCodeAttribute) AddTo ¶ added in v0.3.0
func (c ErrorCodeAttribute) AddTo(m *Message) error
AddTo adds ERROR-CODE to m.
func (*ErrorCodeAttribute) GetFrom ¶ added in v0.3.0
func (c *ErrorCodeAttribute) GetFrom(m *Message) error
GetFrom decodes ERROR-CODE from m. Reason is valid until m.Raw is valid.
func (ErrorCodeAttribute) String ¶ added in v0.3.0
func (c ErrorCodeAttribute) String() string
type Event ¶ added in v0.3.0
type Event struct { TransactionID [TransactionIDSize]byte Message *Message Error error }
Event is passed to Handler describing the transaction event. Do not reuse outside Handler.
type FingerprintAttr ¶ added in v0.3.0
type FingerprintAttr struct{}
FingerprintAttr represents FINGERPRINT attribute.
var Fingerprint FingerprintAttr //nolint:gochecknoglobals
Fingerprint is shorthand for FingerprintAttr.
Example:
m := New() Fingerprint.AddTo(m)
func (FingerprintAttr) AddTo ¶ added in v0.3.0
func (FingerprintAttr) AddTo(m *Message) error
AddTo adds fingerprint to message.
func (FingerprintAttr) Check ¶ added in v0.3.0
func (FingerprintAttr) Check(m *Message) error
Check reads fingerprint value from m and checks it, returning error if any. Can return *AttrLengthErr, ErrAttributeNotFound, and *CRCMismatch.
type Handler ¶ added in v0.3.0
type Handler func(e Event)
Handler handles state changes of transaction.
Handler is called on transaction state change. Usage of e is valid only during call, user must copy needed fields explicitly.
type MappedAddress ¶ added in v0.3.0
MappedAddress represents MAPPED-ADDRESS attribute.
This attribute is used only by servers for achieving backwards compatibility with RFC 3489 clients.
func (*MappedAddress) AddTo ¶ added in v0.3.0
func (a *MappedAddress) AddTo(m *Message) error
AddTo adds MAPPED-ADDRESS to message.
func (*MappedAddress) AddToAs ¶ added in v0.4.0
func (a *MappedAddress) AddToAs(m *Message, t AttrType) error
AddToAs adds MAPPED-ADDRESS value to m as t attribute.
func (*MappedAddress) GetFrom ¶ added in v0.3.0
func (a *MappedAddress) GetFrom(m *Message) error
GetFrom decodes MAPPED-ADDRESS from message.
func (*MappedAddress) GetFromAs ¶ added in v0.4.0
func (a *MappedAddress) GetFromAs(m *Message, t AttrType) error
GetFromAs decodes MAPPED-ADDRESS value in message m as an attribute of type t.
func (MappedAddress) String ¶ added in v0.3.0
func (a MappedAddress) String() string
type Message ¶
type Message struct { Type MessageType Length uint32 // len(Raw) not including header TransactionID [TransactionIDSize]byte Attributes Attributes Raw []byte }
Message represents a single STUN packet. It uses aggressive internal buffering to enable zero-allocation encoding and decoding, so there are some usage constraints:
Message, its fields, results of m.Get or any attribute a.GetFrom are valid only until Message.Raw is not modified.
Example ¶
buf := new(bytes.Buffer) m := new(Message) m.Build(BindingRequest, //nolint:errcheck,gosec NewTransactionIDSetter([TransactionIDSize]byte{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, }), NewSoftware("ernado/stun"), NewLongTermIntegrity("username", "realm", "password"), Fingerprint, ) // Instead of calling Build, use AddTo(m) directly for all setters // to reduce allocations. // For example: // software := NewSoftware("ernado/stun") // software.AddTo(m) // no allocations // Or pass software as follows: // m.Build(&software) // no allocations // If you pass software as value, there will be 1 allocation. // This rule is correct for all setters. fmt.Println(m, "buff length:", len(m.Raw)) n, err := m.WriteTo(buf) fmt.Println("wrote", n, "err", err) // Decoding from buf new *Message. decoded := new(Message) decoded.Raw = make([]byte, 0, 1024) // for ReadFrom that reuses m.Raw // ReadFrom does not allocate internal buffer for reading from io.Reader, // instead it uses m.Raw, expanding it length to capacity. decoded.ReadFrom(buf) //nolint:errcheck,gosec fmt.Println("has software:", decoded.Contains(AttrSoftware)) fmt.Println("has nonce:", decoded.Contains(AttrNonce)) var software Software decoded.Parse(&software) //nolint:errcheck,gosec // Rule for Parse method is same as for Build. fmt.Println("software:", software) if err := Fingerprint.Check(decoded); err == nil { fmt.Println("fingerprint is correct") } else { fmt.Println("fingerprint is incorrect:", err) } // Checking integrity i := NewLongTermIntegrity("username", "realm", "password") if err := i.Check(decoded); err == nil { fmt.Println("integrity ok") } else { fmt.Println("integrity bad:", err) } fmt.Println("for corrupted message:") decoded.Raw[22] = 33 if Fingerprint.Check(decoded) == nil { fmt.Println("fingerprint: ok") } else { fmt.Println("fingerprint: failed") }
Output: Binding request l=48 attrs=3 id=AQIDBAUGBwgJAAEA, attr0=SOFTWARE attr1=MESSAGE-INTEGRITY attr2=FINGERPRINT buff length: 68 wrote 68 err <nil> has software: true has nonce: false software: ernado/stun fingerprint is correct integrity ok for corrupted message: fingerprint: failed
func (*Message) Add ¶ added in v0.3.0
Add appends new attribute to message. Not goroutine-safe.
Value of attribute is copied to internal buffer so it is safe to reuse v.
func (*Message) AddTo ¶ added in v0.3.0
AddTo sets b.TransactionID to m.TransactionID.
Implements Setter to aid in crafting responses.
func (*Message) Build ¶ added in v0.3.0
Build resets message and applies setters to it in batch, returning on first error. To prevent allocations, pass pointers to values.
Example:
var ( t = BindingRequest username = NewUsername("username") nonce = NewNonce("nonce") realm = NewRealm("example.org") ) m := new(Message) m.Build(t, username, nonce, realm) // 4 allocations m.Build(&t, &username, &nonce, &realm) // 0 allocations
See BenchmarkBuildOverhead.
func (*Message) Check ¶ added in v0.3.0
Check applies checkers to message in batch, returning on first error.
func (*Message) Encode ¶ added in v0.3.0
func (m *Message) Encode()
Encode re-encodes message into m.Raw.
func (*Message) ForEach ¶ added in v0.3.0
ForEach is helper that iterates over message attributes allowing to call Getter in f callback to get all attributes of type t and returning on first f error.
The m.Get method inside f will be returning next attribute on each f call. Does not error if there are no results.
Example ¶
m := MustBuild(NewRealm("realm1"), NewRealm("realm2")) if err := m.ForEach(AttrRealm, func(m *Message) error { var r Realm if err := r.GetFrom(m); err != nil { return err } fmt.Println(r) return nil }); err != nil { fmt.Println("error:", err) }
Output: realm1 realm2
func (*Message) Get ¶ added in v0.3.0
Get returns byte slice that represents attribute value, if there is no attribute with such type, ErrAttributeNotFound is returned.
func (Message) MarshalBinary ¶ added in v0.4.0
MarshalBinary implements the encoding.BinaryMarshaler interface.
func (*Message) NewTransactionID ¶ added in v0.3.0
NewTransactionID sets m.TransactionID to random value from crypto/rand and returns error if any.
func (*Message) Parse ¶ added in v0.3.0
Parse applies getters to message in batch, returning on first error.
func (*Message) ReadFrom ¶ added in v0.3.0
ReadFrom implements ReaderFrom. Reads message from r into m.Raw, Decodes it and return error if any. If m.Raw is too small, will return ErrUnexpectedEOF, ErrUnexpectedHeaderEOF or *DecodeErr.
Can return *DecodeErr while decoding too.
func (*Message) Reset ¶ added in v0.3.0
func (m *Message) Reset()
Reset resets Message, attributes and underlying buffer length.
func (*Message) SetType ¶ added in v0.3.0
func (m *Message) SetType(t MessageType)
SetType sets m.Type and writes it to m.Raw.
func (*Message) UnmarshalBinary ¶ added in v0.4.0
UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
func (*Message) Write ¶ added in v0.3.0
Write decodes message and return error if any.
Any error is unrecoverable, but message could be partially decoded.
func (*Message) WriteAttributes ¶ added in v0.3.0
func (m *Message) WriteAttributes()
WriteAttributes encodes all m.Attributes to m.
func (*Message) WriteHeader ¶ added in v0.3.0
func (m *Message) WriteHeader()
WriteHeader writes header to underlying buffer. Not goroutine-safe.
func (*Message) WriteLength ¶ added in v0.3.0
func (m *Message) WriteLength()
WriteLength writes m.Length to m.Raw.
func (*Message) WriteTo ¶ added in v0.3.0
WriteTo implements WriterTo via calling Write(m.Raw) on w and returning call result.
func (*Message) WriteTransactionID ¶ added in v0.3.0
func (m *Message) WriteTransactionID()
WriteTransactionID writes m.TransactionID to m.Raw.
type MessageClass ¶
type MessageClass byte
MessageClass is 8-bit representation of 2-bit class of STUN Message Class.
const ( ClassRequest MessageClass = 0x00 // 0b00 ClassIndication MessageClass = 0x01 // 0b01 ClassSuccessResponse MessageClass = 0x02 // 0b10 ClassErrorResponse MessageClass = 0x03 // 0b11 )
Possible values for message class in STUN Message Type.
func (MessageClass) String ¶
func (c MessageClass) String() string
type MessageIntegrity ¶
type MessageIntegrity []byte
MessageIntegrity represents MESSAGE-INTEGRITY attribute.
AddTo and Check methods are using zero-allocation version of hmac, see newHMAC function and internal/hmac/pool.go.
func NewLongTermIntegrity ¶ added in v0.3.0
func NewLongTermIntegrity(username, realm, password string) MessageIntegrity
NewLongTermIntegrity returns new MessageIntegrity with key for long-term credentials. Password, username, and realm must be SASL-prepared.
func NewShortTermIntegrity ¶ added in v0.3.0
func NewShortTermIntegrity(password string) MessageIntegrity
NewShortTermIntegrity returns new MessageIntegrity with key for short-term credentials. Password must be SASL-prepared.
func (MessageIntegrity) AddTo ¶ added in v0.3.0
func (i MessageIntegrity) AddTo(m *Message) error
AddTo adds MESSAGE-INTEGRITY attribute to message.
CPU costly, see BenchmarkMessageIntegrity_AddTo.
func (MessageIntegrity) Check ¶ added in v0.3.0
func (i MessageIntegrity) Check(m *Message) error
Check checks MESSAGE-INTEGRITY attribute.
CPU costly, see BenchmarkMessageIntegrity_Check.
func (MessageIntegrity) String ¶ added in v0.3.0
func (i MessageIntegrity) String() string
type MessageType ¶ added in v0.3.0
type MessageType struct { Method Method // e.g. binding Class MessageClass // e.g. request }
MessageType is STUN Message Type Field.
func NewType ¶ added in v0.3.0
func NewType(method Method, class MessageClass) MessageType
NewType returns new message type with provided method and class.
func (MessageType) AddTo ¶ added in v0.3.0
func (t MessageType) AddTo(m *Message) error
AddTo sets m type to t.
func (*MessageType) ReadValue ¶ added in v0.3.0
func (t *MessageType) ReadValue(v uint16)
ReadValue decodes uint16 into MessageType.
func (MessageType) String ¶ added in v0.3.0
func (t MessageType) String() string
func (MessageType) Value ¶ added in v0.3.0
func (t MessageType) Value() uint16
Value returns bit representation of messageType.
type Method ¶
type Method uint16
Method is uint16 representation of 12-bit STUN method.
const ( MethodBinding Method = 0x001 MethodAllocate Method = 0x003 MethodRefresh Method = 0x004 MethodSend Method = 0x006 MethodData Method = 0x007 MethodCreatePermission Method = 0x008 MethodChannelBind Method = 0x009 )
Possible methods for STUN Message.
type Nonce ¶
type Nonce []byte
Nonce represents NONCE attribute.
type OtherAddress ¶ added in v0.3.4
OtherAddress represents OTHER-ADDRESS attribute.
func (*OtherAddress) AddTo ¶ added in v0.3.4
func (o *OtherAddress) AddTo(m *Message) error
AddTo adds OTHER-ADDRESS attribute to message.
func (*OtherAddress) GetFrom ¶ added in v0.3.4
func (o *OtherAddress) GetFrom(m *Message) error
GetFrom decodes OTHER-ADDRESS from message.
func (OtherAddress) String ¶ added in v0.3.4
func (o OtherAddress) String() string
type ProtoType ¶ added in v0.6.0
type ProtoType int
ProtoType indicates the transport protocol type that is used in the ice.URL structure.
func NewProtoType ¶ added in v0.6.0
NewProtoType defines a procedure for creating a new ProtoType from a raw string naming the transport protocol type.
type RawAttribute ¶
RawAttribute is a Type-Length-Value (TLV) object that can be added to a STUN message. Attributes are divided into two types: comprehension-required and comprehension-optional. STUN agents can safely ignore comprehension-optional attributes they don't understand, but cannot successfully process a message if it contains comprehension-required attributes that are not understood.
func (RawAttribute) AddTo ¶ added in v0.3.0
func (a RawAttribute) AddTo(m *Message) error
AddTo implements Setter, adding attribute as a.Type with a.Value and ignoring the Length field.
func (RawAttribute) Equal ¶ added in v0.3.0
func (a RawAttribute) Equal(b RawAttribute) bool
Equal returns true if a == b.
func (RawAttribute) String ¶ added in v0.3.0
func (a RawAttribute) String() string
type Realm ¶
type Realm []byte
Realm represents REALM attribute.
type ResponseOrigin ¶ added in v0.4.0
ResponseOrigin represents RESPONSE-ORIGIN attribute.
func (*ResponseOrigin) AddTo ¶ added in v0.4.0
func (o *ResponseOrigin) AddTo(m *Message) error
AddTo adds RESPONSE-ORIGIN attribute to message.
func (*ResponseOrigin) GetFrom ¶ added in v0.4.0
func (o *ResponseOrigin) GetFrom(m *Message) error
GetFrom decodes RESPONSE-ORIGIN from message.
func (ResponseOrigin) String ¶ added in v0.4.0
func (o ResponseOrigin) String() string
type SchemeType ¶ added in v0.6.0
type SchemeType int
SchemeType indicates the type of server used in the ice.URL structure.
const ( // SchemeTypeUnknown indicates an unknown or unsupported scheme. SchemeTypeUnknown SchemeType = iota // SchemeTypeSTUN indicates the URL represents a STUN server. SchemeTypeSTUN // SchemeTypeSTUNS indicates the URL represents a STUNS (secure) server. SchemeTypeSTUNS // SchemeTypeTURN indicates the URL represents a TURN server. SchemeTypeTURN // SchemeTypeTURNS indicates the URL represents a TURNS (secure) server. SchemeTypeTURNS )
func NewSchemeType ¶ added in v0.6.0
func NewSchemeType(raw string) SchemeType
NewSchemeType defines a procedure for creating a new SchemeType from a raw string naming the scheme type.
func (SchemeType) String ¶ added in v0.6.0
func (t SchemeType) String() string
type Setter ¶ added in v0.3.0
Setter sets *Message attribute.
var TransactionID Setter = transactionIDSetter{} //nolint:gochecknoglobals
TransactionID is Setter for m.TransactionID.
func NewTransactionIDSetter ¶ added in v0.3.0
func NewTransactionIDSetter(value [TransactionIDSize]byte) Setter
NewTransactionIDSetter returns new Setter that sets message transaction id to provided value.
type Software ¶
type Software []byte
Software is SOFTWARE attribute.
func NewSoftware ¶ added in v0.3.0
NewSoftware returns *Software from string.
type StopErr ¶ added in v0.3.0
type StopErr struct { Err error // value returned by Stop() Cause error // error that caused Stop() call }
StopErr occurs when Client fails to stop transaction while processing error.
type TextAttribute ¶ added in v0.3.0
type TextAttribute []byte
TextAttribute is helper for adding and getting text attributes.
type URI ¶ added in v0.3.0
type URI struct { Scheme SchemeType Host string Port int Username string Password string Proto ProtoType }
URI represents a STUN (rfc7064) or TURN (rfc7065) URI
func ParseURI ¶ added in v0.3.0
ParseURI parses a STUN or TURN urls following the ABNF syntax described in https://tools.ietf.org/html/rfc7064 and https://tools.ietf.org/html/rfc7065 respectively.
type UnknownAttributes ¶
type UnknownAttributes []AttrType
UnknownAttributes represents UNKNOWN-ATTRIBUTES attribute.
func (UnknownAttributes) AddTo ¶ added in v0.3.0
func (a UnknownAttributes) AddTo(m *Message) error
AddTo adds UNKNOWN-ATTRIBUTES attribute to message.
func (*UnknownAttributes) GetFrom ¶ added in v0.3.0
func (a *UnknownAttributes) GetFrom(m *Message) error
GetFrom parses UNKNOWN-ATTRIBUTES from message.
func (UnknownAttributes) String ¶ added in v0.3.0
func (a UnknownAttributes) String() string
type Username ¶
type Username []byte
Username represents USERNAME attribute.
func NewUsername ¶ added in v0.3.0
NewUsername returns Username with provided value.
type XORMappedAddress ¶ added in v0.3.0
XORMappedAddress implements XOR-MAPPED-ADDRESS attribute.
func (XORMappedAddress) AddTo ¶ added in v0.3.0
func (a XORMappedAddress) AddTo(m *Message) error
AddTo adds XOR-MAPPED-ADDRESS to m. Can return ErrBadIPLength if len(a.IP) is invalid.
func (XORMappedAddress) AddToAs ¶ added in v0.3.0
func (a XORMappedAddress) AddToAs(m *Message, t AttrType) error
AddToAs adds XOR-MAPPED-ADDRESS value to m as t attribute.
func (*XORMappedAddress) GetFrom ¶ added in v0.3.0
func (a *XORMappedAddress) GetFrom(m *Message) error
GetFrom decodes XOR-MAPPED-ADDRESS attribute in message and returns error if any. While decoding, a.IP is reused if possible and can be rendered to invalid state (e.g. if a.IP was set to IPv6 and then IPv4 value were decoded into it), be careful.
Example:
expectedIP := net.ParseIP("213.141.156.236") expectedIP.String() // 213.141.156.236, 16 bytes, first 12 of them are zeroes expectedPort := 21254 addr := &XORMappedAddress{ IP: expectedIP, Port: expectedPort, } // addr were added to message that is decoded as newMessage // ... addr.GetFrom(newMessage) addr.IP.String() // 213.141.156.236, net.IPv4Len expectedIP.String() // d58d:9cec::ffff:d58d:9cec, 16 bytes, first 4 are IPv4 // now we have len(expectedIP) = 16 and len(addr.IP) = 4.
func (*XORMappedAddress) GetFromAs ¶ added in v0.3.0
func (a *XORMappedAddress) GetFromAs(m *Message, t AttrType) error
GetFromAs decodes XOR-MAPPED-ADDRESS attribute value in message getting it as for t type.
func (XORMappedAddress) String ¶ added in v0.3.0
func (a XORMappedAddress) String() string
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
cmd
|
|
stun-bench
Package main implements benchmarks for the STUN package
|
Package main implements benchmarks for the STUN package |
stun-client
Package main implements a CLI tool which acts as a STUN client
|
Package main implements a CLI tool which acts as a STUN client |
stun-decode
Package main implements a simple CLI tool to decode STUN messages
|
Package main implements a simple CLI tool to decode STUN messages |
stun-multiplex
Command stun-multiplex is example of doing UDP connection multiplexing that splits incoming UDP packets to two streams, "STUN Data" and "Application Data".
|
Command stun-multiplex is example of doing UDP connection multiplexing that splits incoming UDP packets to two streams, "STUN Data" and "Application Data". |
stun-nat-behaviour
This package implements RFC5780's tests: - 4.3.
|
This package implements RFC5780's tests: - 4.3. |
stun-traversal
Package main implements a simple CLI tools to perform NAT traversal via STUN
|
Package main implements a simple CLI tools to perform NAT traversal via STUN |
Package main implement end-to-end tests
|
Package main implement end-to-end tests |
internal
|
|
hmac
Package hmac implements the Keyed-Hash Message Authentication Code (HMAC) as defined in U.S. Federal Information Processing Standards Publication 198.
|
Package hmac implements the Keyed-Hash Message Authentication Code (HMAC) as defined in U.S. Federal Information Processing Standards Publication 198. |
testutil
Package testutil contains helpers and utilities for writing tests
|
Package testutil contains helpers and utilities for writing tests |
Package stuntest contains helpers for testing STUN clients
|
Package stuntest contains helpers for testing STUN clients |