Documentation ¶
Index ¶
- Variables
- func ClientRequestAddRecordRoute(c *Client, r *sip.Request) error
- func ClientRequestAddVia(c *Client, r *sip.Request) error
- func ClientRequestBuild(c *Client, r *sip.Request) error
- func ClientRequestDecreaseMaxForward(c *Client, r *sip.Request) error
- func GenerateTLSConfig(certFile string, keyFile string, rootPems []byte) (*tls.Config, error)
- func Init()
- type AnswerOptions
- type Client
- func (c *Client) Close() error
- func (c *Client) DoDigestAuth(ctx context.Context, req *sip.Request, res *sip.Response, auth DigestAuth) (sip.ClientTransaction, error)
- func (c *Client) GetHostname() string
- func (c *Client) TransactionRequest(ctx context.Context, req *sip.Request, options ...ClientRequestOption) (sip.ClientTransaction, error)
- func (c *Client) WriteRequest(req *sip.Request, options ...ClientRequestOption) error
- type ClientOption
- type ClientRequestOption
- type Dialog
- type DialogClient
- func (c *DialogClient) Invite(ctx context.Context, recipient sip.Uri, body []byte, headers ...sip.Header) (*DialogClientSession, error)
- func (c *DialogClient) ReadBye(req *sip.Request, tx sip.ServerTransaction) error
- func (c *DialogClient) ReadRefer(req *sip.Request, tx sip.ServerTransaction, referUri *sip.Uri) (*DialogClientSession, error)
- func (c *DialogClient) WriteInvite(ctx context.Context, inviteRequest *sip.Request) (*DialogClientSession, error)
- type DialogClientSession
- func (s *DialogClientSession) Ack(ctx context.Context) error
- func (s *DialogClientSession) Bye(ctx context.Context) error
- func (s *DialogClientSession) Close() error
- func (s *DialogClientSession) TransactionRequest(ctx context.Context, req *sip.Request) (sip.ClientTransaction, error)
- func (s *DialogClientSession) WaitAnswer(ctx context.Context, opts AnswerOptions) error
- func (s *DialogClientSession) WriteAck(ctx context.Context, ack *sip.Request) error
- func (s *DialogClientSession) WriteBye(ctx context.Context, bye *sip.Request) error
- func (s *DialogClientSession) WriteRequest(req *sip.Request) error
- type DialogServer
- type DialogServerSession
- func (s *DialogServerSession) Bye(ctx context.Context) error
- func (s *DialogServerSession) Close() error
- func (s *DialogServerSession) Respond(statusCode sip.StatusCode, reason string, body []byte, headers ...sip.Header) error
- func (s *DialogServerSession) RespondSDP(sdp []byte) error
- func (s *DialogServerSession) TransactionRequest(ctx context.Context, req *sip.Request) (sip.ClientTransaction, error)
- func (s *DialogServerSession) WriteRequest(req *sip.Request) error
- func (s *DialogServerSession) WriteResponse(res *sip.Response) error
- type DigestAuth
- type ErrDialogResponse
- type ListenReadyCtxValue
- type RequestHandler
- type Server
- func (srv *Server) Close() error
- func (srv *Server) ListenAndServe(ctx context.Context, network string, addr string) error
- func (srv *Server) ListenAndServeTLS(ctx context.Context, network string, addr string, conf *tls.Config) error
- func (srv *Server) OnAck(handler RequestHandler)
- func (srv *Server) OnBye(handler RequestHandler)
- func (srv *Server) OnCancel(handler RequestHandler)
- func (srv *Server) OnInfo(handler RequestHandler)
- func (srv *Server) OnInvite(handler RequestHandler)
- func (srv *Server) OnMessage(handler RequestHandler)
- func (srv *Server) OnNoRoute(handler RequestHandler)
- func (srv *Server) OnNotify(handler RequestHandler)
- func (srv *Server) OnOptions(handler RequestHandler)
- func (srv *Server) OnPrack(handler RequestHandler)
- func (srv *Server) OnPublish(handler RequestHandler)
- func (srv *Server) OnRefer(handler RequestHandler)
- func (srv *Server) OnRegister(handler RequestHandler)
- func (srv *Server) OnRequest(method sip.RequestMethod, handler RequestHandler)
- func (srv *Server) OnSubscribe(handler RequestHandler)
- func (srv *Server) OnUpdate(handler RequestHandler)
- func (srv *Server) RegisteredMethods() []string
- func (srv *Server) ServeRequest(f func(r *sip.Request))
- func (srv *Server) ServeTCP(l net.Listener) error
- func (srv *Server) ServeTLS(l net.Listener) error
- func (srv *Server) ServeUDP(l net.PacketConn) error
- func (srv *Server) ServeWS(l net.Listener) error
- func (srv *Server) ServeWSS(l net.Listener) error
- func (srv *Server) TransportLayer() *sip.TransportLayer
- func (srv *Server) WriteResponse(r *sip.Response) error
- type ServerOption
- type UserAgent
- type UserAgentOption
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrDialogOutsideDialog = errors.New("Call/Transaction outside dialog") ErrDialogDoesNotExists = errors.New("Dialog Does Not Exist") ErrDialogInviteNoContact = errors.New("No Contact header") ErrDialogCanceled = errors.New("Dialog canceled") )
var (
// Used only for testing, better way is to pass listener with Serve{Transport}
ListenReadyCtxKey = "ListenReadyCtxKey"
)
Functions ¶
func ClientRequestAddRecordRoute ¶
ClientRequestAddRecordRoute is option for adding record route header Based on proxy setup https://www.rfc-editor.org/rfc/rfc3261#section-16
func ClientRequestAddVia ¶
ClientRequestAddVia is option for adding via header Based on proxy setup https://www.rfc-editor.org/rfc/rfc3261.html#section-16.6
func ClientRequestBuild ¶
ClientRequestBuild will build missing fields in request This is by default but can be used to combine with other ClientRequestOptions
func ClientRequestDecreaseMaxForward ¶
Based on proxy setup https://www.rfc-editor.org/rfc/rfc3261#section-16 ClientRequestDecreaseMaxForward should be used when forwarding request. It decreases max forward in case of 0 it returnes error
func GenerateTLSConfig ¶
GenerateTLSConfig creates basic tls.Config that you can pass for ServerTLS It needs rootPems for client side
Types ¶
type AnswerOptions ¶
type Client ¶
type Client struct { *UserAgent // contains filtered or unexported fields }
func NewClient ¶
func NewClient(ua *UserAgent, options ...ClientOption) (*Client, error)
NewClient creates client handle for user agent
func (*Client) Close ¶
Close client handle. UserAgent must be closed for full transaction and transport layer closing.
func (*Client) DoDigestAuth ¶
func (c *Client) DoDigestAuth(ctx context.Context, req *sip.Request, res *sip.Response, auth DigestAuth) (sip.ClientTransaction, error)
DoDigestAuth will apply digest authentication if initial request is chalenged by 401 or 407. It returns new transaction that is created for this request
func (*Client) GetHostname ¶
func (*Client) TransactionRequest ¶
func (c *Client) TransactionRequest(ctx context.Context, req *sip.Request, options ...ClientRequestOption) (sip.ClientTransaction, error)
TransactionRequest uses transaction layer to send request and returns transaction
NOTE: By default request will not be cloned and it will populate request with missing headers unless options are used In most cases you want this as you will retry with additional headers
Following header fields will be added if not exist to have correct SIP request: To, From, CSeq, Call-ID, Max-Forwards, Via
Passing options will override this behavior, that is it is expected that you have request fully built This is useful when using client handle in proxy building as request are already parsed
func (*Client) WriteRequest ¶
func (c *Client) WriteRequest(req *sip.Request, options ...ClientRequestOption) error
WriteRequest sends request directly to transport layer Behavior is same as TransactionRequest Non-transaction ACK request should be passed like this
type ClientOption ¶
func WithClientAddr ¶
func WithClientAddr(addr string) ClientOption
WithClientAddr is merge of WithClientHostname and WithClientPort addr is format <host>:<port>
func WithClientHostname ¶
func WithClientHostname(hostname string) ClientOption
WithClientHost allows setting default route host or IP on Via in case of IP it will enforce transport layer to create/reuse connection with this IP default: user agent IP This is useful when you need to act as client first and avoid creating server handle listeners. NOTE: From header hostname is WithUserAgentHostname option on UA or modify request manually
func WithClientLogger ¶
func WithClientLogger(logger zerolog.Logger) ClientOption
WithClientLogger allows customizing client logger
func WithClientNAT ¶
func WithClientNAT() ClientOption
WithClientNAT makes client aware that is behind NAT.
func WithClientPort ¶
func WithClientPort(port int) ClientOption
WithClientPort allows setting default route Via port it will enforce transport layer to create connection with this port if does NOT exist transport layer will choose existing connection by default unless TransportLayer.ConnectionReuse is set to false default: ephemeral port
type Dialog ¶
type Dialog struct { ID string // InviteRequest is set when dialog is created. It is not thread safe! // Use it only as read only and use methods to change headers InviteRequest *sip.Request // InviteResponse is last response received or sent. It is not thread safe! // Use it only as read only and do not change values InviteResponse *sip.Response // contains filtered or unexported fields }
func (*Dialog) State ¶
func (d *Dialog) State() <-chan sip.DialogState
type DialogClient ¶
type DialogClient struct {
// contains filtered or unexported fields
}
func NewDialogClient ¶
func NewDialogClient(client *Client, contactHDR sip.ContactHeader) *DialogClient
NewDialogClient provides handle for managing UAC dialog Contact hdr is default to be provided for correct invite. It is not used if you provided hdr as part of request, but contact hdr must be present so this makes sure correct dialog is established. In case handling different transports you should have multiple instances per transport
func (*DialogClient) Invite ¶
func (c *DialogClient) Invite(ctx context.Context, recipient sip.Uri, body []byte, headers ...sip.Header) (*DialogClientSession, error)
Invite sends INVITE request and creates early dialog session. This is actually not yet dialog (ID is empty) You need to call WaitAnswer after for establishing dialog For passing custom Invite request use WriteInvite
func (*DialogClient) ReadBye ¶
func (c *DialogClient) ReadBye(req *sip.Request, tx sip.ServerTransaction) error
func (*DialogClient) ReadRefer ¶
func (c *DialogClient) ReadRefer(req *sip.Request, tx sip.ServerTransaction, referUri *sip.Uri) (*DialogClientSession, error)
Experiment ReadRefer reads REFER (Transfer action) and parses referURI if dialog exists. Returned dialog you should use to pass NOTIFY and BYE if your new INVITE dialog is successful
func (*DialogClient) WriteInvite ¶
func (c *DialogClient) WriteInvite(ctx context.Context, inviteRequest *sip.Request) (*DialogClientSession, error)
type DialogClientSession ¶
type DialogClientSession struct { Dialog // contains filtered or unexported fields }
func (*DialogClientSession) Ack ¶
func (s *DialogClientSession) Ack(ctx context.Context) error
Ack sends ack. Use WriteAck for more customizing
func (*DialogClientSession) Bye ¶
func (s *DialogClientSession) Bye(ctx context.Context) error
Bye sends bye and terminates session. Use WriteBye if you want to customize bye request
func (*DialogClientSession) Close ¶
func (s *DialogClientSession) Close() error
Close must be always called in order to cleanup some internal resources Consider that this will not send BYE or CANCEL or change dialog state
func (*DialogClientSession) TransactionRequest ¶
func (s *DialogClientSession) TransactionRequest(ctx context.Context, req *sip.Request) (sip.ClientTransaction, error)
TransactionRequest is doing client DIALOG request based on RFC https://www.rfc-editor.org/rfc/rfc3261#section-12.2.1 This ensures that you have proper request done within dialog. You should avoid setting any Dialog header (cseq, from, to, callid)
func (*DialogClientSession) WaitAnswer ¶
func (s *DialogClientSession) WaitAnswer(ctx context.Context, opts AnswerOptions) error
WaitAnswer waits for success response or returns ErrDialogResponse in case non 2xx Canceling context while waiting 2xx will send Cancel request Returns errors: - ErrDialogResponse in case non 2xx response - any internal in case waiting answer failed for different reasons
func (*DialogClientSession) WriteRequest ¶
func (s *DialogClientSession) WriteRequest(req *sip.Request) error
type DialogServer ¶
type DialogServer struct {
// contains filtered or unexported fields
}
func NewDialogServer ¶
func NewDialogServer(client *Client, contactHDR sip.ContactHeader) *DialogServer
NewDialogServer provides handle for managing UAS dialog Contact hdr is default that is provided for responses. Client is needed for termination dialog session In case handling different transports you should have multiple instances per transport
func (*DialogServer) ReadAck ¶
func (s *DialogServer) ReadAck(req *sip.Request, tx sip.ServerTransaction) error
ReadAck should read from your OnAck handler
func (*DialogServer) ReadBye ¶
func (s *DialogServer) ReadBye(req *sip.Request, tx sip.ServerTransaction) error
ReadBye should read from your OnBye handler
func (*DialogServer) ReadInvite ¶
func (s *DialogServer) ReadInvite(req *sip.Request, tx sip.ServerTransaction) (*DialogServerSession, error)
ReadInvite should read from your OnInvite handler for which it creates dialog context You need to use DialogServerSession for all further responses Do not forget to add ReadAck and ReadBye for confirming dialog and terminating
type DialogServerSession ¶
type DialogServerSession struct { Dialog // contains filtered or unexported fields }
func (*DialogServerSession) Close ¶
func (s *DialogServerSession) Close() error
Close is always good to call for cleanup or terminating dialog state
func (*DialogServerSession) Respond ¶
func (s *DialogServerSession) Respond(statusCode sip.StatusCode, reason string, body []byte, headers ...sip.Header) error
Respond should be called for Invite request, you may want to call this multiple times like 100 Progress or 180 Ringing 2xx for creating dialog or other code in case failure
In case Cancel request received: ErrDialogCanceled is responded
func (*DialogServerSession) RespondSDP ¶
func (s *DialogServerSession) RespondSDP(sdp []byte) error
RespondSDP is just wrapper to call 200 with SDP. It is better to use this when answering as it provide correct headers
func (*DialogServerSession) TransactionRequest ¶
func (s *DialogServerSession) TransactionRequest(ctx context.Context, req *sip.Request) (sip.ClientTransaction, error)
TransactionRequest is doing client DIALOG request based on RFC https://www.rfc-editor.org/rfc/rfc3261#section-12.2.1 This ensures that you have proper request done within dialog
func (*DialogServerSession) WriteRequest ¶
func (s *DialogServerSession) WriteRequest(req *sip.Request) error
func (*DialogServerSession) WriteResponse ¶
func (s *DialogServerSession) WriteResponse(res *sip.Response) error
WriteResponse allows passing you custom response
type DigestAuth ¶
type ErrDialogResponse ¶
func (ErrDialogResponse) Error ¶
func (e ErrDialogResponse) Error() string
type ListenReadyCtxValue ¶
type ListenReadyCtxValue chan struct{}
type RequestHandler ¶
type RequestHandler func(req *sip.Request, tx sip.ServerTransaction)
RequestHandler is a callback that will be called on the incoming request
type Server ¶
type Server struct { *UserAgent // contains filtered or unexported fields }
Server is a SIP server
func NewServer ¶
func NewServer(ua *UserAgent, options ...ServerOption) (*Server, error)
NewServer creates new instance of SIP server handle. Allows creating server transaction handlers It uses User Agent transport and transaction layer
func (*Server) Close ¶
Close server handle. UserAgent must be closed for full transaction and transport layer closing.
func (*Server) ListenAndServe ¶
Serve will fire all listeners Network supported: udp, tcp, ws
func (*Server) ListenAndServeTLS ¶
func (srv *Server) ListenAndServeTLS(ctx context.Context, network string, addr string, conf *tls.Config) error
Serve will fire all listeners that are secured. Network supported: tls, wss
func (*Server) OnAck ¶
func (srv *Server) OnAck(handler RequestHandler)
OnAck registers Ack request handler
func (*Server) OnBye ¶
func (srv *Server) OnBye(handler RequestHandler)
OnBye registers Bye request handler
func (*Server) OnCancel ¶
func (srv *Server) OnCancel(handler RequestHandler)
OnCancel registers Cancel request handler
func (*Server) OnInfo ¶
func (srv *Server) OnInfo(handler RequestHandler)
OnInfo registers Info request handler
func (*Server) OnInvite ¶
func (srv *Server) OnInvite(handler RequestHandler)
OnInvite registers Invite request handler
func (*Server) OnMessage ¶
func (srv *Server) OnMessage(handler RequestHandler)
OnMessage registers Message request handler
func (*Server) OnNoRoute ¶
func (srv *Server) OnNoRoute(handler RequestHandler)
OnNoRoute registers no route handler default is handling is responding 405 Method Not allowed This allows customizing your response for any non handled message
Example ¶
// Creating no route handler allows you to respond for non handled (non routed) requests ua, _ := NewUA() srv, _ := NewServer(ua) srv.OnNoRoute(func(req *sip.Request, tx sip.ServerTransaction) { res := sip.NewResponseFromRequest(req, 405, "Method Not Allowed", nil) // Send response directly and let transaction terminate if err := srv.WriteResponse(res); err != nil { srv.log.Error().Err(err).Msg("respond '405 Method Not Allowed' failed") } })
Output:
func (*Server) OnNotify ¶
func (srv *Server) OnNotify(handler RequestHandler)
OnNotify registers Notify request handler
func (*Server) OnOptions ¶
func (srv *Server) OnOptions(handler RequestHandler)
OnOptions registers Options request handler
func (*Server) OnPrack ¶
func (srv *Server) OnPrack(handler RequestHandler)
OnPrack registers Prack request handler
func (*Server) OnPublish ¶
func (srv *Server) OnPublish(handler RequestHandler)
OnPublish registers Publish request handler
func (*Server) OnRefer ¶
func (srv *Server) OnRefer(handler RequestHandler)
OnRefer registers Refer request handler
func (*Server) OnRegister ¶
func (srv *Server) OnRegister(handler RequestHandler)
OnRegister registers Register request handler
func (*Server) OnRequest ¶
func (srv *Server) OnRequest(method sip.RequestMethod, handler RequestHandler)
OnRequest registers new request callback. Can be used as generic way to add handler
func (*Server) OnSubscribe ¶
func (srv *Server) OnSubscribe(handler RequestHandler)
OnSubscribe registers Subscribe request handler
func (*Server) OnUpdate ¶
func (srv *Server) OnUpdate(handler RequestHandler)
OnUpdate registers Update request handler
func (*Server) RegisteredMethods ¶
RegisteredMethods returns list of registered handlers. Can be used for constructing Allow header
func (*Server) ServeRequest ¶
ServeRequest can be used as middleware for preprocessing message
func (*Server) ServeUDP ¶
func (srv *Server) ServeUDP(l net.PacketConn) error
ServeUDP starts serving request on UDP type listener.
func (*Server) TransportLayer ¶
func (srv *Server) TransportLayer() *sip.TransportLayer
Transport is function to get transport layer of server Can be used for modifying
type ServerOption ¶
func WithServerLogger ¶
func WithServerLogger(logger zerolog.Logger) ServerOption
WithServerLogger allows customizing server logger
type UserAgent ¶
type UserAgent struct {
// contains filtered or unexported fields
}
func NewUA ¶
func NewUA(options ...UserAgentOption) (*UserAgent, error)
NewUA creates User Agent User Agent will create transport and transaction layer Check options for customizing user agent
func (*UserAgent) TransactionLayer ¶
func (ua *UserAgent) TransactionLayer() *sip.TransactionLayer
func (*UserAgent) TransportLayer ¶
func (ua *UserAgent) TransportLayer() *sip.TransportLayer
type UserAgentOption ¶
func WithUserAgenTLSConfig ¶
func WithUserAgenTLSConfig(c *tls.Config) UserAgentOption
WithUserAgenTLSConfig allows customizing default tls config.
func WithUserAgent ¶
func WithUserAgent(ua string) UserAgentOption
WithUserAgent changes user agent name Default: sipgo
func WithUserAgentDNSResolver ¶
func WithUserAgentDNSResolver(r *net.Resolver) UserAgentOption
WithUserAgentDNSResolver allows customizing default DNS resolver for transport layer
func WithUserAgentHostname ¶
func WithUserAgentHostname(hostname string) UserAgentOption
WithUserAgentHostname represents FQDN of user that can be presented in From header
func WithUserAgentParser ¶
func WithUserAgentParser(p *sip.Parser) UserAgentOption