transaction

package
v1.4.2 Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package transaction provides SIP UDP transaction helpers layered under pkg/sip/stack.Endpoint.

UAC (client):

  • INVITE client: RunInviteClient, HandleResponse (wire from stack.Endpoint.OnSIPResponse), ACK helpers.

UAS INVITE (server):

  • RegisterPendingInviteServer when an INVITE arrives before the final; ClearPendingInviteServer or let BeginInviteServer clear it after a final.
  • HandleCancelRequest for CANCEL matching pending Call-ID + CSeq (sends 200 to CANCEL); TU still sends 487 (or similar) on INVITE.
  • After sending a final on the wire: BeginInviteServer; duplicate INVITE: HandleInviteRequest; 2xx: HandleAck.

UAS non-INVITE (OPTIONS, REGISTER, …):

  • After sending a final: BeginNonInviteServer; duplicate request: HandleNonInviteRequest (Timer J window).

Keys: InviteTransactionKey(branch, Call-ID); NonInviteServerKey(req) for non-INVITE map.

TCP/TLS signaling is handled at pkg/sip/server (per-connection framing via stack.ReadMessage); this package still lacks RFC 3261 connection reuse / outbound TX mirroring for TCP.

Not implemented: forked responses, full PRACK/re-INVITE state machines beyond invite_rfc3262 hooks, every non-INVITE server-transaction edge case.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AckRequestURIFor2xx

func AckRequestURIFor2xx(resp *stack.Message, inviteRequestURI string) string

AckRequestURIFor2xx prefers Contact from a 2xx response (RFC 3261 dialog establishment).

func BranchParam

func BranchParam(viaLine string) string

BranchParam extracts the branch parameter from one Via field-value (case-insensitive "branch=").

func BuildAckForInvite

func BuildAckForInvite(invite *stack.Message, final *stack.Message, requestURI string) (*stack.Message, error)

BuildAckForInvite builds an ACK for the completed INVITE transaction. For status 200–299, requestURI should usually be AckRequestURIFor2xx(resp, invite.RequestURI). For 300–699, requestURI should be the same as the INVITE Request-URI (RFC 3261 §17.1.1.2).

func InviteTransactionKey

func InviteTransactionKey(branch, callID string) string

InviteTransactionKey is the INVITE transaction map key (top Via branch + Call-ID).

func IsAckCSeq

func IsAckCSeq(m *stack.Message) bool

IsAckCSeq reports whether the CSeq header refers to method ACK.

func IsCancelCSeq

func IsCancelCSeq(m *stack.Message) bool

IsCancelCSeq reports whether the CSeq header refers to method CANCEL.

func IsInviteCSeq

func IsInviteCSeq(m *stack.Message) bool

IsInviteCSeq reports whether the CSeq header refers to method INVITE.

func NonInviteServerKey

func NonInviteServerKey(req *stack.Message) string

NonInviteServerKey builds a stable key for a non-INVITE request (branch + Call-ID + method + CSeq number).

func RouteHeadersForDialog

func RouteHeadersForDialog(resp *stack.Message) []string

RouteHeadersForDialog returns Route header field-values for a subsequent in-dialog request, derived from Record-Route on a dialog-creating 2xx (reverse of Record-Route appearance order).

func SetTransactionTimeoutHook

func SetTransactionTimeoutHook(fn func(method string))

SetTransactionTimeoutHook lets tests intercept timer-B/F firings without touching the metrics registry. Pass nil to reset to the default sipMetrics-backed emitter.

func TopBranch

func TopBranch(m *stack.Message) string

TopBranch returns BranchParam(TopVia(m)).

func TopVia

func TopVia(m *stack.Message) string

TopVia returns the first Via header field-value (SIP message order: top-most Via).

Types

type InviteClientResult

type InviteClientResult struct {
	Final  *stack.Message
	Remote *net.UDPAddr // UDP source of the last response (use for ACK / subsequent in-dialog routing).
}

InviteClientResult is the outcome of a completed INVITE client transaction over UDP.

type Manager

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

Manager routes SIP responses to UAC client transactions and tracks UAS INVITE / non-INVITE server transactions.

func NewManager

func NewManager() *Manager

NewManager creates a manager with RFC default T1 = 500ms and T2 = 4s.

func (*Manager) BeginInviteServer

func (m *Manager) BeginInviteServer(ctx context.Context, invite *stack.Message, remote *net.UDPAddr, final *stack.Message, send SendFunc) error

BeginInviteServer registers a UAS INVITE transaction after the TU has sent a final response (2xx–6xx). For UDP, duplicate INVITE retransmissions must receive the same final (use HandleInviteRequest). For 2xx, Timer G retransmits until HandleAck sees the matching ACK.

func (*Manager) BeginNonInviteServer

func (m *Manager) BeginNonInviteServer(ctx context.Context, req *stack.Message, remote *net.UDPAddr, final *stack.Message, send SendFunc) error

BeginNonInviteServer registers a UAS non-INVITE transaction after the TU sent a final response (e.g. 200 to OPTIONS/REGISTER).

func (*Manager) ClearPendingInviteServer

func (m *Manager) ClearPendingInviteServer(callID string)

ClearPendingInviteServer removes the pending INVITE record for Call-ID.

func (*Manager) HandleAck

func (m *Manager) HandleAck(ack *stack.Message, _ *net.UDPAddr) bool

HandleAck matches an ACK to a pending INVITE server transaction and stops retransmissions.

func (*Manager) HandleCancelRequest

func (m *Manager) HandleCancelRequest(cancel *stack.Message, addr *net.UDPAddr, send SendFunc) bool

HandleCancelRequest handles an inbound CANCEL matching a pending INVITE (same Call-ID and CSeq number). It sends 200 OK to CANCEL via send, clears the pending record, and returns true. The TU should still send a final response to the INVITE (e.g. 487).

func (*Manager) HandleInviteRequest

func (m *Manager) HandleInviteRequest(req *stack.Message, addr *net.UDPAddr) bool

HandleInviteRequest handles a retransmitted INVITE: resends the stored final to addr (fallback: tx.remote).

func (*Manager) HandleNonInviteRequest

func (m *Manager) HandleNonInviteRequest(req *stack.Message, addr *net.UDPAddr) bool

HandleNonInviteRequest handles a retransmitted non-INVITE request: resends the stored final if still in Timer J window.

func (*Manager) HandleResponse

func (m *Manager) HandleResponse(resp *stack.Message, src *net.UDPAddr) bool

HandleResponse dispatches a SIP response to a matching client transaction (INVITE or non-INVITE such as BYE). Returns true if the message was consumed by a transaction (including duplicate finals). src is the UDP source of the datagram (used for symmetric routing of ACK/subsequent requests).

func (*Manager) RegisterPendingInviteServer

func (m *Manager) RegisterPendingInviteServer(inv *stack.Message) error

RegisterPendingInviteServer records an inbound INVITE before a final response is sent, so CANCEL with the same Call-ID and CSeq number can be matched (RFC 3261). Clear with ClearPendingInviteServer or automatically when BeginInviteServer runs.

func (*Manager) RunInviteClient

func (m *Manager) RunInviteClient(ctx context.Context, invite *stack.Message, remote *net.UDPAddr, send SendFunc, onProvisional func(*stack.Message)) (*InviteClientResult, error)

RunInviteClient registers an INVITE client transaction, sends the INVITE (and UDP retransmits until a provisional or final response), then blocks until ctx is done or a final (2xx–6xx) arrives.

onProvisional is optional; it is invoked at most once for the first 1xx response. Wire HandleResponse on the same Manager from stack.Endpoint.OnSIPResponse.

func (*Manager) RunNonInviteClient

func (m *Manager) RunNonInviteClient(ctx context.Context, req *stack.Message, remote *net.UDPAddr, send SendFunc) (*NonInviteClientResult, error)

RunNonInviteClient runs a non-INVITE client transaction (UDP retransmits until a final response). Wire HandleResponse on the same Manager from stack.Endpoint.OnSIPResponse.

func (*Manager) SetT1

func (m *Manager) SetT1(d time.Duration)

SetT1 sets the initial INVITE retransmission interval (must be > 0). Intended for tests.

func (*Manager) SetT2

func (m *Manager) SetT2(d time.Duration)

SetT2 sets the Timer G maximum interval for 2xx retransmissions (must be > 0). Default 4s.

type NonInviteClientResult

type NonInviteClientResult struct {
	Final  *stack.Message
	Remote *net.UDPAddr
}

NonInviteClientResult is the outcome of a completed non-INVITE client transaction (e.g. BYE).

type SendFunc

type SendFunc func(msg *stack.Message, addr *net.UDPAddr) error

SendFunc sends a SIP request datagram.

Jump to

Keyboard shortcuts

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