sip

package
v0.22.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 2, 2024 License: BSD-2-Clause Imports: 22 Imported by: 0

README

SIP stack in GO

This SIP stack for RFC:

https://datatracker.ietf.org/doc/html/rfc3261

Stack:

  • Encoding/Decoding with Parser optimized for fast parsing
  • Transport Layer and support for different protocols
  • Transaction Layer with transaction sessions managing and state machine

Parser

Parser by default parses set of headers that are mostly present in messages. From,To,Via,Cseq,Content-Type,Content-Length... This headers are accessible via fast reference msg.Via(), msg.From()...

This can be configured using WithHeadersParsers and reducing this to increase performance. SIP stack in case needed will use fast reference and lazy parsing.

Documentation

Overview

Originally forked from https://github.com/ghettovoice/gosip by @ghetovoice

Index

Constants

View Source
const (
	MTU uint = 1500

	DefaultHost     = "127.0.0.1"
	DefaultProtocol = "UDP"

	DefaultUdpPort int = 5060
	DefaultTcpPort int = 5060
	DefaultTlsPort int = 5061
	DefaultWsPort  int = 80
	DefaultWssPort int = 443

	RFC3261BranchMagicCookie = "z9hG4bK"
)
View Source
const (
	// Transport for different sip messages. GO uses lowercase, but for message parsing, we should
	// use this constants for setting message Transport
	TransportUDP = "UDP"
	TransportTCP = "TCP"
	TransportTLS = "TLS"
	TransportWS  = "WS"
	TransportWSS = "WSS"

	// TransportFixedLengthMessage sets message size limit for parsing and avoids stream parsing
	TransportFixedLengthMessage uint16 = 0
)
View Source
const (
	FsmInputNone fsmInput = iota
)

FSM Inputs

Variables

View Source
var (
	ErrParseLineNoCRLF = errors.New("line has no CRLF")
	ErrParseEOF        = errors.New("EOF on reading line")

	// Stream parse errors
	ErrParseSipPartial         = errors.New("SIP partial data")
	ErrParseReadBodyIncomplete = errors.New("reading body incomplete")
	ErrParseMoreMessages       = errors.New("Stream has more message")
)
View Source
var (
	// SIP timers are exposed for manipulation but best approach is using SetTimers
	// where all timers get populated based on
	// T1: Round-trip time (RTT) estimate, Default 500ms
	T1,

	T2,

	T4,

	Timer_A,

	Timer_B,
	Timer_D,
	Timer_E,

	Timer_F,
	Timer_G,
	Timer_H,
	Timer_I,
	Timer_J,
	Timer_K,
	Timer_L,
	Timer_M time.Duration

	Timer_1xx = 200 * time.Millisecond

	TxSeperator = "__"

	TransactionFSMDebug bool
)
View Source
var (
	// Transaction Layer Errors can be detected and handled with different response on caller side
	// https://www.rfc-editor.org/rfc/rfc3261#section-8.1.3.1
	ErrTransactionTimeout   = errors.New("transaction timeout")
	ErrTransactionTransport = errors.New("transaction transport error")
)
View Source
var (
	SIPDebug bool

	// IdleConnection will keep connections idle even after transaction terminate
	// -1 	- single response or request will close
	// 0 	- close connection immediatelly after transaction terminate
	// 1 	- keep connection idle after transaction termination
	IdleConnection int = 1
)
View Source
var (
	UDPMTUSize = 1500

	// UDPUseConnectedConnection will force creating UDP connected connection
	UDPUseConnectedConnection = false

	ErrUDPMTUCongestion = errors.New("size of packet larger than MTU")
)
View Source
var (

	// Errors
	ErrTransportNotSuported = errors.New("protocol not supported")
)
View Source
var (
	// WebSocketProtocols is used in setting websocket header
	// By default clients must accept protocol sip
	WebSocketProtocols = []string{"sip"}
)

Functions

func ASCIIToLower

func ASCIIToLower(s string) string

ASCIIToLower is faster than go version. It avoids one more loop

func ASCIIToLowerInPlace

func ASCIIToLowerInPlace(s []byte)

func CopyHeaders

func CopyHeaders(name string, from, to Message)

Copy all headers of one type from one message to another. Appending to any headers that were already there.

func DefaultHeadersParser

func DefaultHeadersParser() map[string]HeaderParser

DefaultHeadersParser returns minimal version header parser. It can be extended or overwritten. Removing some defaults can break SIP functionality

NOTE this API call may change

func DefaultPort

func DefaultPort(transport string) int

DefaultPort returns transport default port by network.

func GenerateBranch

func GenerateBranch() string

GenerateBranch returns random unique branch ID.

func GenerateBranchN

func GenerateBranchN(n int) string

GenerateBranchN returns random unique branch ID in format MagicCookie.<n chars>

func GenerateTagN

func GenerateTagN(n int) string

func HeaderToLower

func HeaderToLower(s string) string

HeaderToLower is fast ASCII lower string

func IsReliable

func IsReliable(network string) bool

func MakeClientTxKey

func MakeClientTxKey(msg Message) (string, error)

MakeClientTxKey creates client key for matching responses - RFC 3261 17.1.3.

func MakeDialogID

func MakeDialogID(callID, innerID, externalID string) string

func MakeDialogIDFromRequest

func MakeDialogIDFromRequest(msg *Request) (string, error)

MakeDialogIDFromMessage creates dialog ID of message. Use UASReadRequestDialogID UACReadRequestDialogID for more specific returns error if callid or to tag or from tag does not exists

func MakeDialogIDFromResponse

func MakeDialogIDFromResponse(msg *Response) (string, error)

MakeDialogIDFromResponse creates dialog ID of message. returns error if callid or to tag or from tag does not exists

func MakeServerTxKey

func MakeServerTxKey(msg Message) (string, error)

MakeServerTxKey creates server key for matching retransmitting requests - RFC 3261 17.2.3.

func MessageShortString

func MessageShortString(msg Message) string

MessageShortString dumps short version of msg. Used only for logging

func NetworkToLower

func NetworkToLower(network string) string

NetworkToLower is faster function converting UDP, TCP to udp, tcp

func NonceWrite

func NonceWrite(buf []byte)

func ParseAddr

func ParseAddr(addr string) (host string, port int, err error)

func ParseAddressValue

func ParseAddressValue(addressText string, uri *Uri, headerParams HeaderParams) (displayName string, err error)

ParseAddressValue parses an address - such as from a From, To, or Contact header. It returns: See RFC 3261 section 20.10 for details on parsing an address.

func ParseUri

func ParseUri(uriStr string, uri *Uri) (err error)

ParseUri converts a string representation of a URI into a Uri object. Following https://datatracker.ietf.org/doc/html/rfc3261#section-19.1.1 sip:user:password@host:port;uri-parameters?headers

func ResolveInterfacesIP

func ResolveInterfacesIP(network string, targetIP net.IP) (net.IP, net.Interface, error)

ResolveInterfaceIP will check current interfaces and resolve to IP Using targetIP it will try to match interface with same subnet network can be "ip" "ip4" "ip6" by default it avoids loopack IP unless targetIP is loopback

func ResolveSelfIP

func ResolveSelfIP() (net.IP, error)

ResolveSelfIP returns first non loopback IP

Deprecated use ResolveInterfacesIP

func SetTimers

func SetTimers(t1, t2, t4 time.Duration)

func SplitByWhitespace

func SplitByWhitespace(text string) []string

Splits the given string into sections, separated by one or more characters from c_ABNF_WS.

func UACReadRequestDialogID

func UACReadRequestDialogID(msg *Request) (string, error)

UACReadRequestDialogID creates dialog ID of message if receiver has UAC role. returns error if callid or to tag or from tag does not exists

func UASReadRequestDialogID

func UASReadRequestDialogID(msg *Request) (string, error)

UASReadRequestDialogID creates dialog ID of message if receiver has UAS role. returns error if callid or to tag or from tag does not exists

func UnmarshalParams

func UnmarshalParams(s string, seperator rune, ending rune, p HeaderParams) (n int, err error)

func UriIsSIP

func UriIsSIP(s string) bool

Check uri is SIP fast

func UriIsSIPS

func UriIsSIPS(s string) bool

Types

type Addr

type Addr struct {
	IP       net.IP // Must be in IP format
	Port     int
	Hostname string // Original hostname before resolved to IP
}

func (*Addr) String

func (a *Addr) String() string

type CSeqHeader

type CSeqHeader struct {
	SeqNo      uint32
	MethodName RequestMethod
}

CSeq is CSeq header

func (*CSeqHeader) Name

func (h *CSeqHeader) Name() string

func (*CSeqHeader) String

func (h *CSeqHeader) String() string

func (*CSeqHeader) StringWrite

func (h *CSeqHeader) StringWrite(buffer io.StringWriter)

func (*CSeqHeader) Value

func (h *CSeqHeader) Value() string

func (*CSeqHeader) ValueStringWrite

func (h *CSeqHeader) ValueStringWrite(buffer io.StringWriter)

type CallIDHeader

type CallIDHeader string

CallIDHeader is a Call-ID header presentation

func (*CallIDHeader) Name

func (h *CallIDHeader) Name() string

func (*CallIDHeader) String

func (h *CallIDHeader) String() string

func (*CallIDHeader) StringWrite

func (h *CallIDHeader) StringWrite(buffer io.StringWriter)

func (*CallIDHeader) Value

func (h *CallIDHeader) Value() string

type ClientTransaction

type ClientTransaction interface {
	Transaction
	// Responses returns channel with all responses for transaction
	Responses() <-chan *Response
	// Cancel sends cancel request
	// TODO: Do we need context passing here?
	Cancel() error
}

type ClientTx

type ClientTx struct {
	// contains filtered or unexported fields
}

func NewClientTx

func NewClientTx(key string, origin *Request, conn Connection, logger zerolog.Logger) *ClientTx

func (*ClientTx) Cancel

func (tx *ClientTx) Cancel() error

Cancel cancels client transaction by sending CANCEL request

func (*ClientTx) Done

func (tx *ClientTx) Done() <-chan struct{}

func (*ClientTx) Err

func (tx *ClientTx) Err() error

func (*ClientTx) Init

func (tx *ClientTx) Init() error

func (*ClientTx) Key

func (tx *ClientTx) Key() string

func (*ClientTx) OnTerminate

func (tx *ClientTx) OnTerminate(f FnTxTerminate)

func (*ClientTx) Origin

func (tx *ClientTx) Origin() *Request

func (*ClientTx) Responses

func (tx *ClientTx) Responses() <-chan *Response

func (*ClientTx) String

func (tx *ClientTx) String() string

func (*ClientTx) Terminate

func (tx *ClientTx) Terminate()

type Connection

type Connection interface {
	// LocalAddr used for connection
	LocalAddr() net.Addr
	// WriteMsg marshals message and sends to socket
	WriteMsg(msg Message) error
	// Reference of connection can be increased/decreased to prevent closing to earlyss
	Ref(i int) int
	// Close decreases reference and if ref = 0 closes connection. Returns last ref. If 0 then it is closed
	TryClose() (int, error)

	Close() error
}

type ConnectionPool

type ConnectionPool struct {
	// TODO consider sync.Map way with atomic checks to reduce mutex contention
	sync.RWMutex
	// contains filtered or unexported fields
}

func NewConnectionPool

func NewConnectionPool() ConnectionPool

func (*ConnectionPool) Add

func (p *ConnectionPool) Add(a string, c Connection)

func (*ConnectionPool) AddIfNotExists

func (p *ConnectionPool) AddIfNotExists(a string, c Connection)

func (*ConnectionPool) Clear

func (p *ConnectionPool) Clear()

Clear will clear all connection from pool and close them

func (*ConnectionPool) CloseAndDelete

func (p *ConnectionPool) CloseAndDelete(c Connection, addr string)

CloseAndDelete closes connection and deletes from pool

func (*ConnectionPool) Delete

func (p *ConnectionPool) Delete(addr string)

func (*ConnectionPool) DeleteMultiple

func (p *ConnectionPool) DeleteMultiple(addrs []string)

func (*ConnectionPool) Get

func (p *ConnectionPool) Get(a string) (c Connection)

Getting connection pool increases reference Make sure you TryClose after finish

func (*ConnectionPool) Size

func (p *ConnectionPool) Size() int

type ContactHeader

type ContactHeader struct {
	// The display name from the header, may be omitted.
	DisplayName string
	Address     Uri
	// Any parameters present in the header.
	Params HeaderParams
}

ContactHeader is Contact header representation

func (*ContactHeader) Clone

func (h *ContactHeader) Clone() *ContactHeader

func (*ContactHeader) Name

func (h *ContactHeader) Name() string

func (*ContactHeader) String

func (h *ContactHeader) String() string

func (*ContactHeader) StringWrite

func (h *ContactHeader) StringWrite(buffer io.StringWriter)

func (*ContactHeader) Value

func (h *ContactHeader) Value() string

type ContentLengthHeader

type ContentLengthHeader uint32

ContentLengthHeader is Content-Length header representation

func (*ContentLengthHeader) Name

func (h *ContentLengthHeader) Name() string

func (ContentLengthHeader) String

func (h ContentLengthHeader) String() string

func (ContentLengthHeader) StringWrite

func (h ContentLengthHeader) StringWrite(buffer io.StringWriter)

func (ContentLengthHeader) Value

func (h ContentLengthHeader) Value() string

type ContentTypeHeader

type ContentTypeHeader string

ContentTypeHeader is Content-Type header representation.

func (*ContentTypeHeader) Name

func (h *ContentTypeHeader) Name() string

func (h **ContentTypeHeader) Name() string { return "Content-Type" }

func (*ContentTypeHeader) String

func (h *ContentTypeHeader) String() string

func (*ContentTypeHeader) StringWrite

func (h *ContentTypeHeader) StringWrite(buffer io.StringWriter)

func (*ContentTypeHeader) Value

func (h *ContentTypeHeader) Value() string

type CopyHeader

type CopyHeader interface {
	// contains filtered or unexported methods
}

CopyHeader is internal interface for cloning headers. Maybe it will be full exposed later

type DialogState

type DialogState int
const (
	// Dialog received 200 response
	DialogStateEstablished DialogState = 1
	// Dialog received ACK
	DialogStateConfirmed DialogState = 2
	// Dialog received BYE
	DialogStateEnded DialogState = 3
)

func (DialogState) String

func (s DialogState) String() string

type ErrorHandler

type ErrorHandler func(err error)

type ExpiresHeader

type ExpiresHeader uint32

ExpiresHeader is Expires header representation

func (*ExpiresHeader) Name

func (h *ExpiresHeader) Name() string

func (*ExpiresHeader) String

func (h *ExpiresHeader) String() string

func (*ExpiresHeader) StringWrite

func (h *ExpiresHeader) StringWrite(buffer io.StringWriter)

func (ExpiresHeader) Value

func (h ExpiresHeader) Value() string

type FnTxTerminate

type FnTxTerminate func(key string)

type FromHeader

type FromHeader struct {
	// The display name from the header, may be omitted.
	DisplayName string

	Address Uri

	// Any parameters present in the header.
	Params HeaderParams
}

func (*FromHeader) Name

func (h *FromHeader) Name() string

func (*FromHeader) Next

func (header *FromHeader) Next() Header

func (*FromHeader) String

func (h *FromHeader) String() string

func (*FromHeader) StringWrite

func (h *FromHeader) StringWrite(buffer io.StringWriter)

func (*FromHeader) Value

func (h *FromHeader) Value() string

func (*FromHeader) ValueStringWrite

func (h *FromHeader) ValueStringWrite(buffer io.StringWriter)
type Header interface {
	// Name returns header name.
	Name() string
	Value() string
	String() string
	// StringWrite is better way to reuse single buffer
	StringWrite(w io.StringWriter)
	// contains filtered or unexported methods
}

Header is a single SIP header.

func HeaderClone

func HeaderClone(h Header) Header

HeaderClone is generic function for cloning header

func NewHeader

func NewHeader(name, value string) Header

NewHeader creates generic type of header

type HeaderKV

type HeaderKV struct {
	K string
	V string
}

type HeaderParams

type HeaderParams map[string]string

HeaderParams are key value params. They do not provide order by default due to performance reasons

func NewParams

func NewParams() HeaderParams

Create an empty set of parameters.

func (HeaderParams) Add

func (hp HeaderParams) Add(key string, val string) Params

Add will add new key:val. If key exists it will be overwriten

func (HeaderParams) Clone

func (hp HeaderParams) Clone() Params

Clone returns underneath map copied

func (HeaderParams) Equals

func (hp HeaderParams) Equals(other interface{}) bool

Equals check if two maps of parameters are equal in the sense of having the same keys with the same values. This does not rely on any ordering of the keys of the map in memory.

func (HeaderParams) Get

func (hp HeaderParams) Get(key string) (string, bool)

Get returns existing key

func (HeaderParams) Has

func (hp HeaderParams) Has(key string) bool

Has checks does key exists

func (HeaderParams) Items

func (hp HeaderParams) Items() map[string]string

Items returns the entire parameter map.

func (HeaderParams) Keys

func (hp HeaderParams) Keys() []string

Keys return a slice of keys, in order.

func (HeaderParams) Length

func (hp HeaderParams) Length() int

Length returns number of params.

func (HeaderParams) Remove

func (hp HeaderParams) Remove(key string) Params

Remove removes param with exact key

func (HeaderParams) String

func (hp HeaderParams) String() string

String returns params joined with '&' char.

func (HeaderParams) ToString

func (hp HeaderParams) ToString(sep uint8) string

ToString renders params to a string. Note that this does not escape special characters, this should already have been done before calling this method.

func (HeaderParams) ToStringWrite

func (hp HeaderParams) ToStringWrite(sep uint8, buffer io.StringWriter)

ToStringWrite is same as ToString but it stores to defined buffer instead returning string

type HeaderParser

type HeaderParser func(headerName string, headerData string) (Header, error)

A HeaderParser is any function that turns raw header data into one or more Header objects.

type MaxForwardsHeader

type MaxForwardsHeader uint32

MaxForwardsHeader is Max-Forwards header representation

func (*MaxForwardsHeader) Dec

func (h *MaxForwardsHeader) Dec()

func (*MaxForwardsHeader) Name

func (h *MaxForwardsHeader) Name() string

func (*MaxForwardsHeader) String

func (h *MaxForwardsHeader) String() string

func (*MaxForwardsHeader) StringWrite

func (h *MaxForwardsHeader) StringWrite(buffer io.StringWriter)

func (MaxForwardsHeader) Val

func (h MaxForwardsHeader) Val() uint32

func (*MaxForwardsHeader) Value

func (h *MaxForwardsHeader) Value() string

type Message

type Message interface {
	// String returns string representation of SIP message in RFC 3261 form.
	String() string
	// String write is same as String but lets you to provide writter and reduce allocations
	StringWrite(io.StringWriter)
	// GetHeaders returns slice of headers of the given type.
	GetHeaders(name string) []Header
	// PrependHeader prepends header to message.
	PrependHeader(header ...Header)
	// AppendHeader appends header to message.
	AppendHeader(header Header)
	// CallID returns 'Call-ID' header.
	CallID() *CallIDHeader
	// Via returns the top 'Via' header field.
	Via() *ViaHeader
	// From returns 'From' header field.
	From() *FromHeader
	// To returns 'To' header field.
	To() *ToHeader
	// CSeq returns 'CSeq' header field.
	CSeq() *CSeqHeader
	// Body returns message body.
	Body() []byte
	// SetBody sets message body.
	SetBody(body []byte)

	Transport() string
	SetTransport(tp string)
	Source() string
	SetSource(src string)
	Destination() string
	SetDestination(dest string)
}

func ParseMessage

func ParseMessage(msgData []byte) (Message, error)

type MessageData

type MessageData struct {

	// Set to 2.0 version by default
	SipVersion string
	// contains filtered or unexported fields
}

func (*MessageData) AppendHeader

func (hs *MessageData) AppendHeader(header Header)

AppendHeader adds header at end of header list

func (*MessageData) AppendHeaderAfter

func (hs *MessageData) AppendHeaderAfter(header Header, name string)

AppendHeaderAfter adds header after specified header. In case header does not exist normal AppendHeader is called Use it only if you need it

func (*MessageData) Body

func (msg *MessageData) Body() []byte

func (*MessageData) CSeq

func (hs *MessageData) CSeq() *CSeqHeader

CSeq returns CSEQ parsed header or nil if not exists

func (*MessageData) CallID

func (hs *MessageData) CallID() *CallIDHeader

CallID returns CallID parsed header or nil if not exists

func (*MessageData) CloneHeaders

func (hs *MessageData) CloneHeaders() []Header

CloneHeaders returns all cloned headers in slice.

func (*MessageData) Contact

func (hs *MessageData) Contact() *ContactHeader

Contact returns Contact parsed header or nil if not exists

func (*MessageData) ContentLength

func (hs *MessageData) ContentLength() *ContentLengthHeader

ContentLength returns Content-Length parsed header or nil if not exists

func (*MessageData) ContentType

func (hs *MessageData) ContentType() *ContentTypeHeader

ContentType returns Content-Type parsed header or nil if not exists

func (*MessageData) Destination

func (msg *MessageData) Destination() string

func (*MessageData) From

func (hs *MessageData) From() *FromHeader

From returns From parsed header or nil if not exists

func (*MessageData) GetHeader

func (hs *MessageData) GetHeader(name string) Header

GetHeader returns Header if exists, otherwise nil is returned Use lower case to avoid allocs Headers are pointers, always Clone them for change

func (*MessageData) GetHeaders

func (hs *MessageData) GetHeaders(name string) []Header

GetHeaders returns list of headers with same name Use lower case to avoid allocs Headers are pointers, always Clone them for change

func (*MessageData) Headers

func (hs *MessageData) Headers() []Header

Headers gets some headers.

func (*MessageData) MaxForwards

func (hs *MessageData) MaxForwards() *MaxForwardsHeader

MaxForwards returns Max-Forwards parsed header or nil if not exists

func (*MessageData) PrependHeader

func (hs *MessageData) PrependHeader(headers ...Header)

PrependHeader adds header to the front of header list using as list reduces need of realloc underneath array

func (*MessageData) RecordRoute

func (hs *MessageData) RecordRoute() *RecordRouteHeader

RecordRoute returns Record-Route parsed header or nil if not exists

func (*MessageData) RemoveHeader

func (hs *MessageData) RemoveHeader(name string) (removed bool)

RemoveHeader removes header by name

func (*MessageData) ReplaceHeader

func (hs *MessageData) ReplaceHeader(header Header)

ReplaceHeader replaces first header with same name

func (*MessageData) Route

func (hs *MessageData) Route() *RouteHeader

Route returns Route parsed header or nil if not exists

func (*MessageData) SetBody

func (msg *MessageData) SetBody(body []byte)

SetBody sets message body, calculates it length and add 'Content-Length' header.

func (*MessageData) SetDestination

func (msg *MessageData) SetDestination(dest string)

func (*MessageData) SetSource

func (msg *MessageData) SetSource(src string)

func (*MessageData) SetTransport

func (msg *MessageData) SetTransport(tp string)

func (*MessageData) Source

func (msg *MessageData) Source() string

func (*MessageData) String

func (hs *MessageData) String() string

func (*MessageData) StringWrite

func (hs *MessageData) StringWrite(buffer io.StringWriter)

func (*MessageData) To

func (hs *MessageData) To() *ToHeader

To returns To parsed header or nil if not exists

func (*MessageData) Transport

func (msg *MessageData) Transport() string

func (*MessageData) Via

func (hs *MessageData) Via() *ViaHeader

Via returns Via parsed header or nil if not exists

type MessageHandler

type MessageHandler func(msg Message)

type Params

type Params interface {
	Get(key string) (string, bool)
	Add(key string, val string) Params
	Remove(key string) Params
	Clone() Params
	Equals(params interface{}) bool
	ToString(sep uint8) string
	ToStringWrite(sep uint8, buffer io.StringWriter)
	String() string
	Length() int
	Items() map[string]string
	Keys() []string
	Has(key string) bool
}

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

Parser is implementation of SIPParser It is optimized with faster header parsing

func NewParser

func NewParser(options ...ParserOption) *Parser

Create a new Parser.

func (*Parser) NewSIPStream

func (p *Parser) NewSIPStream() *ParserStream

NewSIPStream implements SIP parsing contructor for IO that stream SIP message It should be created per each stream

func (*Parser) ParseSIP

func (p *Parser) ParseSIP(data []byte) (msg Message, err error)

ParseSIP converts data to sip message. Buffer must contain full sip message

type ParserOption

type ParserOption func(p *Parser)

ParserOption are addition option for NewParser. Check WithParser...

func WithHeadersParsers

func WithHeadersParsers(m map[string]HeaderParser) ParserOption

WithHeadersParsers allows customizing parser headers parsers Consider performance when adding custom parser. Add only if it will appear in almost every message

Check DefaultHeadersParser as starting point

func WithParserLogger

func WithParserLogger(logger zerolog.Logger) ParserOption

WithServerLogger allows customizing parser logger

type ParserStream

type ParserStream struct {
	// contains filtered or unexported fields
}

func (*ParserStream) ParseSIPStream

func (p *ParserStream) ParseSIPStream(data []byte) (msgs []Message, err error)

ParseSIPStream parsing messages comming in stream It has slight overhead vs parsing full message

type RecordRouteHeader

type RecordRouteHeader struct {
	Address Uri
}

RecordRouteHeader is Record-Route header representation.

func (*RecordRouteHeader) Clone

func (*RecordRouteHeader) Name

func (h *RecordRouteHeader) Name() string

func (*RecordRouteHeader) String

func (h *RecordRouteHeader) String() string

func (*RecordRouteHeader) StringWrite

func (h *RecordRouteHeader) StringWrite(buffer io.StringWriter)

func (*RecordRouteHeader) Value

func (h *RecordRouteHeader) Value() string

func (*RecordRouteHeader) ValueStringWrite

func (h *RecordRouteHeader) ValueStringWrite(buffer io.StringWriter)

type Request

type Request struct {
	MessageData
	Method    RequestMethod
	Recipient Uri
}

Request RFC 3261 - 7.1.

func CopyRequest

func CopyRequest(req *Request) *Request

func NewAckRequest

func NewAckRequest(inviteRequest *Request, inviteResponse *Response, body []byte) *Request

NewAckRequest creates ACK request for 2xx INVITE https://tools.ietf.org/html/rfc3261#section-13.2.2.4 NOTE: it does not copy Via header. This is left to transport or caller to enforce Deprecated: use DialogClient for building dialogs

func NewRequest

func NewRequest(method RequestMethod, recipient Uri) *Request

NewRequest creates base for building sip Request A Request-Line contains a method name, a Request-URI, and the SIP/2.0 as version No headers are added. AppendHeader should be called to add Headers. r.SetBody can be called to set proper ContentLength header

func (*Request) AppendHeader

func (hs *Request) AppendHeader(header Header)

AppendHeader adds header at end of header list

func (*Request) AppendHeaderAfter

func (hs *Request) AppendHeaderAfter(header Header, name string)

AppendHeaderAfter adds header after specified header. In case header does not exist normal AppendHeader is called Use it only if you need it

func (*Request) CSeq

func (hs *Request) CSeq() *CSeqHeader

CSeq returns CSEQ parsed header or nil if not exists

func (*Request) CallID

func (hs *Request) CallID() *CallIDHeader

CallID returns CallID parsed header or nil if not exists

func (*Request) Clone

func (req *Request) Clone() *Request

func (*Request) CloneHeaders

func (hs *Request) CloneHeaders() []Header

CloneHeaders returns all cloned headers in slice.

func (*Request) Contact

func (hs *Request) Contact() *ContactHeader

Contact returns Contact parsed header or nil if not exists

func (*Request) ContentLength

func (hs *Request) ContentLength() *ContentLengthHeader

ContentLength returns Content-Length parsed header or nil if not exists

func (*Request) ContentType

func (hs *Request) ContentType() *ContentTypeHeader

ContentType returns Content-Type parsed header or nil if not exists

func (*Request) Destination

func (req *Request) Destination() string

func (*Request) From

func (hs *Request) From() *FromHeader

From returns From parsed header or nil if not exists

func (*Request) GetHeader

func (hs *Request) GetHeader(name string) Header

GetHeader returns Header if exists, otherwise nil is returned Use lower case to avoid allocs Headers are pointers, always Clone them for change

func (*Request) GetHeaders

func (hs *Request) GetHeaders(name string) []Header

GetHeaders returns list of headers with same name Use lower case to avoid allocs Headers are pointers, always Clone them for change

func (*Request) Headers

func (hs *Request) Headers() []Header

Headers gets some headers.

func (*Request) IsAck

func (req *Request) IsAck() bool

func (*Request) IsCancel

func (req *Request) IsCancel() bool

func (*Request) IsInvite

func (req *Request) IsInvite() bool

func (*Request) MaxForwards

func (hs *Request) MaxForwards() *MaxForwardsHeader

MaxForwards returns Max-Forwards parsed header or nil if not exists

func (*Request) PrependHeader

func (hs *Request) PrependHeader(headers ...Header)

PrependHeader adds header to the front of header list using as list reduces need of realloc underneath array

func (*Request) RecordRoute

func (hs *Request) RecordRoute() *RecordRouteHeader

RecordRoute returns Record-Route parsed header or nil if not exists

func (*Request) RemoveHeader

func (hs *Request) RemoveHeader(name string) (removed bool)

RemoveHeader removes header by name

func (*Request) ReplaceHeader

func (hs *Request) ReplaceHeader(header Header)

ReplaceHeader replaces first header with same name

func (*Request) Route

func (hs *Request) Route() *RouteHeader

Route returns Route parsed header or nil if not exists

func (*Request) Short

func (req *Request) Short() string

func (*Request) Source

func (req *Request) Source() string

Source will return host:port address In case of network parsed request source will be connection remote address

func (*Request) StartLine

func (req *Request) StartLine() string

StartLine returns Request Line - RFC 2361 7.1.

func (*Request) StartLineWrite

func (req *Request) StartLineWrite(buffer io.StringWriter)

func (*Request) String

func (req *Request) String() string

func (*Request) StringWrite

func (req *Request) StringWrite(buffer io.StringWriter)

func (*Request) To

func (hs *Request) To() *ToHeader

To returns To parsed header or nil if not exists

func (*Request) Transport

func (req *Request) Transport() string

func (*Request) Via

func (hs *Request) Via() *ViaHeader

Via returns Via parsed header or nil if not exists

type RequestHandler

type RequestHandler func(req *Request, tx ServerTransaction)

type RequestMethod

type RequestMethod string
const (
	INVITE    RequestMethod = "INVITE"
	ACK       RequestMethod = "ACK"
	CANCEL    RequestMethod = "CANCEL"
	BYE       RequestMethod = "BYE"
	REGISTER  RequestMethod = "REGISTER"
	OPTIONS   RequestMethod = "OPTIONS"
	SUBSCRIBE RequestMethod = "SUBSCRIBE"
	NOTIFY    RequestMethod = "NOTIFY"
	REFER     RequestMethod = "REFER"
	INFO      RequestMethod = "INFO"
	MESSAGE   RequestMethod = "MESSAGE"
	PRACK     RequestMethod = "PRACK"
	UPDATE    RequestMethod = "UPDATE"
	PUBLISH   RequestMethod = "PUBLISH"
)

method names are defined here as constants for convenience.

func (RequestMethod) String

func (r RequestMethod) String() string

type Response

type Response struct {
	MessageData

	Reason     string     // e.g. "200 OK"
	StatusCode StatusCode // e.g. 200
}

Response RFC 3261 - 7.2.

func CopyResponse

func CopyResponse(res *Response) *Response

func NewResponse

func NewResponse(
	statusCode StatusCode,
	reason string,
) *Response

NewResponse creates base structure of response.

func NewResponseFromRequest

func NewResponseFromRequest(
	req *Request,
	statusCode StatusCode,
	reason string,
	body []byte,
) *Response

RFC 3261 - 8.2.6

func NewSDPResponseFromRequest

func NewSDPResponseFromRequest(req *Request, body []byte) *Response

NewSDPResponseFromRequest is wrapper for 200 response with SDP body

func (*Response) AppendHeader

func (hs *Response) AppendHeader(header Header)

AppendHeader adds header at end of header list

func (*Response) AppendHeaderAfter

func (hs *Response) AppendHeaderAfter(header Header, name string)

AppendHeaderAfter adds header after specified header. In case header does not exist normal AppendHeader is called Use it only if you need it

func (*Response) CSeq

func (hs *Response) CSeq() *CSeqHeader

CSeq returns CSEQ parsed header or nil if not exists

func (*Response) CallID

func (hs *Response) CallID() *CallIDHeader

CallID returns CallID parsed header or nil if not exists

func (*Response) Clone

func (res *Response) Clone() *Response

func (*Response) CloneHeaders

func (hs *Response) CloneHeaders() []Header

CloneHeaders returns all cloned headers in slice.

func (*Response) Contact

func (hs *Response) Contact() *ContactHeader

Contact returns Contact parsed header or nil if not exists

func (*Response) ContentLength

func (hs *Response) ContentLength() *ContentLengthHeader

ContentLength returns Content-Length parsed header or nil if not exists

func (*Response) ContentType

func (hs *Response) ContentType() *ContentTypeHeader

ContentType returns Content-Type parsed header or nil if not exists

func (*Response) Destination

func (res *Response) Destination() string

Destination will return host:port address In case of building response from request, request source is set as destination This will sent response over same connection if request is parsed from network

func (*Response) From

func (hs *Response) From() *FromHeader

From returns From parsed header or nil if not exists

func (*Response) GetHeader

func (hs *Response) GetHeader(name string) Header

GetHeader returns Header if exists, otherwise nil is returned Use lower case to avoid allocs Headers are pointers, always Clone them for change

func (*Response) GetHeaders

func (hs *Response) GetHeaders(name string) []Header

GetHeaders returns list of headers with same name Use lower case to avoid allocs Headers are pointers, always Clone them for change

func (*Response) Headers

func (hs *Response) Headers() []Header

Headers gets some headers.

func (*Response) IsAck

func (res *Response) IsAck() bool

func (*Response) IsCancel

func (res *Response) IsCancel() bool

func (*Response) IsClientError

func (res *Response) IsClientError() bool

func (*Response) IsGlobalError

func (res *Response) IsGlobalError() bool

func (*Response) IsProvisional

func (res *Response) IsProvisional() bool

func (*Response) IsRedirection

func (res *Response) IsRedirection() bool

func (*Response) IsServerError

func (res *Response) IsServerError() bool

func (*Response) IsSuccess

func (res *Response) IsSuccess() bool

func (*Response) MaxForwards

func (hs *Response) MaxForwards() *MaxForwardsHeader

MaxForwards returns Max-Forwards parsed header or nil if not exists

func (*Response) PrependHeader

func (hs *Response) PrependHeader(headers ...Header)

PrependHeader adds header to the front of header list using as list reduces need of realloc underneath array

func (*Response) RecordRoute

func (hs *Response) RecordRoute() *RecordRouteHeader

RecordRoute returns Record-Route parsed header or nil if not exists

func (*Response) RemoveHeader

func (hs *Response) RemoveHeader(name string) (removed bool)

RemoveHeader removes header by name

func (*Response) ReplaceHeader

func (hs *Response) ReplaceHeader(header Header)

ReplaceHeader replaces first header with same name

func (*Response) Route

func (hs *Response) Route() *RouteHeader

Route returns Route parsed header or nil if not exists

func (*Response) Short

func (res *Response) Short() string

Short is textual short version of response

func (*Response) StartLine

func (res *Response) StartLine() string

StartLine returns Response Status Line - RFC 2361 7.2.

func (*Response) StartLineWrite

func (res *Response) StartLineWrite(buffer io.StringWriter)

func (*Response) String

func (res *Response) String() string

func (*Response) StringWrite

func (res *Response) StringWrite(buffer io.StringWriter)

func (*Response) To

func (hs *Response) To() *ToHeader

To returns To parsed header or nil if not exists

func (*Response) Transport

func (res *Response) Transport() string

func (*Response) Via

func (hs *Response) Via() *ViaHeader

Via returns Via parsed header or nil if not exists

type RouteHeader

type RouteHeader struct {
	Address Uri
}

RouteHeader is Route header representation.

func (*RouteHeader) Clone

func (h *RouteHeader) Clone() *RouteHeader

func (*RouteHeader) Name

func (h *RouteHeader) Name() string

func (*RouteHeader) String

func (h *RouteHeader) String() string

func (*RouteHeader) StringWrite

func (h *RouteHeader) StringWrite(buffer io.StringWriter)

func (*RouteHeader) Value

func (h *RouteHeader) Value() string

func (*RouteHeader) ValueStringWrite

func (h *RouteHeader) ValueStringWrite(buffer io.StringWriter)

type ServerTransaction

type ServerTransaction interface {
	Transaction
	Respond(res *Response) error
	Acks() <-chan *Request
	// Cancels is triggered when transaction is canceled, that is SIP CANCEL is received for transaction.
	Cancels() <-chan *Request
}

type ServerTx

type ServerTx struct {
	// contains filtered or unexported fields
}

func NewServerTx

func NewServerTx(key string, origin *Request, conn Connection, logger zerolog.Logger) *ServerTx

func (*ServerTx) Acks

func (tx *ServerTx) Acks() <-chan *Request

Acks makes channel for sending acks. Channel is created on demand

func (*ServerTx) Cancels

func (tx *ServerTx) Cancels() <-chan *Request

func (*ServerTx) Done

func (tx *ServerTx) Done() <-chan struct{}

func (*ServerTx) Err

func (tx *ServerTx) Err() error

func (*ServerTx) Init

func (tx *ServerTx) Init() error

func (*ServerTx) Key

func (tx *ServerTx) Key() string

func (*ServerTx) OnTerminate

func (tx *ServerTx) OnTerminate(f FnTxTerminate)

func (*ServerTx) Origin

func (tx *ServerTx) Origin() *Request

func (*ServerTx) Receive

func (tx *ServerTx) Receive(req *Request) error

Receive is endpoint for handling received server requests.

func (*ServerTx) Respond

func (tx *ServerTx) Respond(res *Response) error

func (*ServerTx) State

func (tx *ServerTx) State()

func (*ServerTx) String

func (tx *ServerTx) String() string

func (*ServerTx) Terminate

func (tx *ServerTx) Terminate()

type StatusCode

type StatusCode int

StatusCode - response status code: 1xx - 6xx

const (
	// https://datatracker.ietf.org/doc/html/rfc3261#section-21
	StatusTrying            StatusCode = 100
	StatusRinging           StatusCode = 180
	StatusCallIsForwarded   StatusCode = 181
	StatusQueued            StatusCode = 182
	StatusSessionInProgress StatusCode = 183

	StatusOK       StatusCode = 200
	StatusAccepted StatusCode = 202

	StatusMovedPermanently StatusCode = 301
	StatusMovedTemporarily StatusCode = 302
	StatusUseProxy         StatusCode = 305

	StatusBadRequest                   StatusCode = 400
	StatusUnauthorized                 StatusCode = 401
	StatusPaymentRequired              StatusCode = 402
	StatusForbidden                    StatusCode = 403
	StatusNotFound                     StatusCode = 404
	StatusMethodNotAllowed             StatusCode = 405
	StatusNotAcceptable                StatusCode = 406
	StatusProxyAuthRequired            StatusCode = 407
	StatusRequestTimeout               StatusCode = 408
	StatusConflict                     StatusCode = 409
	StatusGone                         StatusCode = 410
	StatusRequestEntityTooLarge        StatusCode = 413
	StatusRequestURITooLong            StatusCode = 414
	StatusUnsupportedMediaType         StatusCode = 415
	StatusRequestedRangeNotSatisfiable StatusCode = 416
	StatusBadExtension                 StatusCode = 420
	StatusExtensionRequired            StatusCode = 421
	StatusIntervalToBrief              StatusCode = 423
	StatusTemporarilyUnavailable       StatusCode = 480
	StatusCallTransactionDoesNotExists StatusCode = 481
	StatusLoopDetected                 StatusCode = 482
	StatusTooManyHops                  StatusCode = 483
	StatusAddressIncomplete            StatusCode = 484
	StatusAmbiguous                    StatusCode = 485
	StatusBusyHere                     StatusCode = 486
	StatusRequestTerminated            StatusCode = 487
	StatusNotAcceptableHere            StatusCode = 488

	StatusInternalServerError StatusCode = 500
	StatusNotImplemented      StatusCode = 501
	StatusBadGateway          StatusCode = 502
	StatusServiceUnavailable  StatusCode = 503
	StatusGatewayTimeout      StatusCode = 504
	StatusVersionNotSupported StatusCode = 505
	StatusMessageTooLarge     StatusCode = 513

	StatusGlobalBusyEverywhere       StatusCode = 600
	StatusGlobalDecline              StatusCode = 603
	StatusGlobalDoesNotExistAnywhere StatusCode = 604
	StatusGlobalNotAcceptable        StatusCode = 606
)

type TCPConnection

type TCPConnection struct {
	net.Conn
	// contains filtered or unexported fields
}

func (*TCPConnection) Close

func (c *TCPConnection) Close() error

func (*TCPConnection) Read

func (c *TCPConnection) Read(b []byte) (n int, err error)

func (*TCPConnection) Ref

func (c *TCPConnection) Ref(i int) int

func (*TCPConnection) TryClose

func (c *TCPConnection) TryClose() (int, error)

func (*TCPConnection) Write

func (c *TCPConnection) Write(b []byte) (n int, err error)

func (*TCPConnection) WriteMsg

func (c *TCPConnection) WriteMsg(msg Message) error

type ToHeader

type ToHeader struct {
	// The display name from the header, may be omitted.
	DisplayName string
	Address     Uri
	// Any parameters present in the header.
	Params HeaderParams
}

ToHeader introduces SIP 'To' header

func (*ToHeader) Name

func (h *ToHeader) Name() string

func (*ToHeader) Next

func (header *ToHeader) Next() Header

func (*ToHeader) String

func (h *ToHeader) String() string

func (*ToHeader) StringWrite

func (h *ToHeader) StringWrite(buffer io.StringWriter)

func (*ToHeader) Value

func (h *ToHeader) Value() string

func (*ToHeader) ValueStringWrite

func (h *ToHeader) ValueStringWrite(buffer io.StringWriter)

type Transaction

type Transaction interface {
	// Terminate will terminate transaction
	Terminate()
	// Done when transaction fsm terminates. Can be called multiple times
	Done() <-chan struct{}
	// Last error. Useful to check when transaction terminates
	Err() error
}

type TransactionLayer

type TransactionLayer struct {
	// contains filtered or unexported fields
}

func NewTransactionLayer

func NewTransactionLayer(tpl *TransportLayer) *TransactionLayer

func (*TransactionLayer) Close

func (txl *TransactionLayer) Close()

func (*TransactionLayer) OnRequest

func (txl *TransactionLayer) OnRequest(h RequestHandler)

func (*TransactionLayer) Request

func (txl *TransactionLayer) Request(ctx context.Context, req *Request) (*ClientTx, error)

func (*TransactionLayer) Respond

func (txl *TransactionLayer) Respond(res *Response) (*ServerTx, error)

func (*TransactionLayer) Transport

func (txl *TransactionLayer) Transport() *TransportLayer

func (*TransactionLayer) UnhandledResponseHandler

func (txl *TransactionLayer) UnhandledResponseHandler(f UnhandledResponseHandler)

UnhandledResponseHandler can be used in case missing client transactions for handling response ServerTransaction handle responses by state machine

type Transport

type Transport interface {
	Network() string

	// GetConnection returns connection from transport
	// addr must be resolved to IP:port
	GetConnection(addr string) (Connection, error)
	CreateConnection(ctx context.Context, laddr Addr, raddr Addr, handler MessageHandler) (Connection, error)
	String() string
	Close() error
}

Protocol implements network specific features.

type TransportLayer

type TransportLayer struct {

	// ConnectionReuse will force connection reuse when passing request
	ConnectionReuse bool

	// PreferSRV does always SRV lookup first
	DNSPreferSRV bool
	// contains filtered or unexported fields
}

TransportLayer implementation.

func NewTransportLayer

func NewTransportLayer(
	dnsResolver *net.Resolver,
	sipparser *Parser,
	tlsConfig *tls.Config,
) *TransportLayer

NewLayer creates transport layer. dns Resolver sip parser tls config - can be nil to use default tls

func (*TransportLayer) ClientRequestConnection

func (l *TransportLayer) ClientRequestConnection(ctx context.Context, req *Request) (c Connection, err error)

ClientRequestConnection is based on https://www.rfc-editor.org/rfc/rfc3261#section-18.1.1 It is wrapper for getting and creating connection

In case req destination is DNS resolved, destination will be cached or in other words SetDestination will be called

func (*TransportLayer) Close

func (l *TransportLayer) Close() error

func (*TransportLayer) GetConnection

func (l *TransportLayer) GetConnection(network, addr string) (Connection, error)

GetConnection gets existing or creates new connection based on addr

func (*TransportLayer) GetListenPort

func (l *TransportLayer) GetListenPort(network string) int

func (*TransportLayer) OnMessage

func (l *TransportLayer) OnMessage(h MessageHandler)

OnMessage is main function which will be called on any new message by transport layer Consider there is no concurency and you need to make sure that you do not block too long This is intentional as higher concurency can slow things

func (*TransportLayer) ServeTCP

func (l *TransportLayer) ServeTCP(c net.Listener) error

ServeTCP will listen on tcp connection

func (*TransportLayer) ServeTLS

func (l *TransportLayer) ServeTLS(c net.Listener) error

ServeTLS will listen on tcp connection

func (*TransportLayer) ServeUDP

func (l *TransportLayer) ServeUDP(c net.PacketConn) error

ServeUDP will listen on udp connection

func (*TransportLayer) ServeWS

func (l *TransportLayer) ServeWS(c net.Listener) error

ServeWS will listen on ws connection

func (*TransportLayer) ServeWSS

func (l *TransportLayer) ServeWSS(c net.Listener) error

ServeWSS will listen on wss connection

func (*TransportLayer) WriteMsg

func (l *TransportLayer) WriteMsg(msg Message) error

func (*TransportLayer) WriteMsgTo

func (l *TransportLayer) WriteMsgTo(msg Message, addr string, network string) error

type UDPConnection

type UDPConnection struct {
	// mutual exclusive for now to avoid interface for Read
	// TODO Refactor
	PacketConn net.PacketConn
	PacketAddr string // For faster matching
	Listener   bool

	Conn net.Conn
	// contains filtered or unexported fields
}

func (*UDPConnection) Close

func (c *UDPConnection) Close() error

func (*UDPConnection) LocalAddr

func (c *UDPConnection) LocalAddr() net.Addr

func (*UDPConnection) Read

func (c *UDPConnection) Read(b []byte) (n int, err error)

func (*UDPConnection) ReadFrom

func (c *UDPConnection) ReadFrom(b []byte) (n int, addr net.Addr, err error)

func (*UDPConnection) Ref

func (c *UDPConnection) Ref(i int) int

func (*UDPConnection) RemoteAddr

func (c *UDPConnection) RemoteAddr() net.Addr

func (*UDPConnection) TryClose

func (c *UDPConnection) TryClose() (int, error)

func (*UDPConnection) Write

func (c *UDPConnection) Write(b []byte) (n int, err error)

func (*UDPConnection) WriteMsg

func (c *UDPConnection) WriteMsg(msg Message) error

func (*UDPConnection) WriteTo

func (c *UDPConnection) WriteTo(b []byte, addr net.Addr) (n int, err error)

type UnhandledResponseHandler

type UnhandledResponseHandler func(req *Response)

type Uri

type Uri struct {
	// True if and only if the URI is a SIPS URI.
	Encrypted bool
	Wildcard  bool

	// The user part of the URI: the 'joe' in sip:joe@bloggs.com
	// This is a pointer, so that URIs without a user part can have 'nil'.
	User string

	// The password field of the URI. This is represented in the URI as joe:hunter2@bloggs.com.
	// Note that if a URI has a password field, it *must* have a user field as well.
	// Note that RFC 3261 strongly recommends against the use of password fields in SIP URIs,
	// as they are fundamentally insecure.
	Password string

	// The host part of the URI. This can be a domain, or a string representation of an IP address.
	Host string

	// The port part of the URI. This is optional, and can be empty.
	Port int

	// Any parameters associated with the URI.
	// These are used to provide information about requests that may be constructed from the URI.
	// (For more details, see RFC 3261 section 19.1.1).
	// These appear as a semicolon-separated list of key=value pairs following the host[:port] part.
	UriParams HeaderParams

	// Any headers to be included on requests constructed from this URI.
	// These appear as a '&'-separated list at the end of the URI, introduced by '?'.
	Headers HeaderParams
}

Uri is parsed form of sip:user:password@host:port;uri-parameters?headers In case of `sips:“ Encrypted is set to true

func (*Uri) Addr

func (uri *Uri) Addr() string

Addr is uri part without headers and params. sip[s]:user@host[:port]

func (*Uri) Clone

func (uri *Uri) Clone() *Uri

Clone

func (*Uri) Endpoint

func (uri *Uri) Endpoint() string

Endpoint is uri user identifier. user@host[:port]

func (*Uri) HostPort

func (uri *Uri) HostPort() string

HostPort represents host:port part

func (*Uri) IsEncrypted

func (uri *Uri) IsEncrypted() bool

IsEncrypted returns true if uri is SIPS uri

func (*Uri) String

func (uri *Uri) String() string

Generates the string representation of a SipUri struct.

func (*Uri) StringWrite

func (uri *Uri) StringWrite(buffer io.StringWriter)

StringWrite writes uri string to buffer

type ViaHeader

type ViaHeader struct {
	// E.g. 'SIP'.
	ProtocolName string
	// E.g. '2.0'.
	ProtocolVersion string
	Transport       string
	// TODO consider changing Host Port as struct Addr from transport
	Host   string
	Port   int // This is optional
	Params HeaderParams
}

ViaHeader is Via header representation. It can be linked list of multiple via if they are part of one header

func (*ViaHeader) Clone

func (h *ViaHeader) Clone() *ViaHeader

func (*ViaHeader) Name

func (h *ViaHeader) Name() string

func (*ViaHeader) SentBy

func (hop *ViaHeader) SentBy() string

func (*ViaHeader) String

func (h *ViaHeader) String() string

func (*ViaHeader) StringWrite

func (h *ViaHeader) StringWrite(buffer io.StringWriter)

func (*ViaHeader) Value

func (h *ViaHeader) Value() string

func (*ViaHeader) ValueStringWrite

func (h *ViaHeader) ValueStringWrite(buffer io.StringWriter)

type WSConnection

type WSConnection struct {
	net.Conn
	// contains filtered or unexported fields
}

func (*WSConnection) Close

func (c *WSConnection) Close() error

func (*WSConnection) Read

func (c *WSConnection) Read(b []byte) (n int, err error)

func (*WSConnection) Ref

func (c *WSConnection) Ref(i int) int

func (*WSConnection) TryClose

func (c *WSConnection) TryClose() (int, error)

func (*WSConnection) Write

func (c *WSConnection) Write(b []byte) (n int, err error)

func (*WSConnection) WriteMsg

func (c *WSConnection) WriteMsg(msg Message) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL