Net::S...Context(3pm)
β¨ Net::SIP::Endpoint::Context π (that's the Net::S...Context(3pm) page bestie, from the User Contributed Perl Documentation) β¨
πΈ NAME πΈ
Net::SIP::Endpoint::Context β it's giving call context for endpoint. That's the whole vibe. π«Ά
π SYNOPSIS π
my $ctx = Net::SIP::Endpoint::Context->new( to => .., from => .. );
my $request = $ctx->new_request(..);
okay so that's literally it, two lines and you're in the group chat π
π¦ DESCRIPTION π¦
This package is the main character that manages the call context β that means from, to, call-id, recorded routes, all of it β for a call to a Net::SIP::Endpoint.
It also keeps the state of the current call on lock: the local and remote cseq, and the current state inside the INVITE transaction. And then it handles requests and responses based on that state. no cap, it's a whole job and it does it. π
π CONSTRUCTOR π
π new ( ARGS ) π
So ARGS is either a hash reference or a hash (both slay, pick your fighter). It has some mandatory keys and some optional ones.
The mandatory keys β these are not optional, periodt:
fromβ the initiator of the call. For outgoing calls this is the local address, for incoming calls it's the peer's address. π«Άtoβ the target of the call. π―
And the optional keys (the little extras that make it cute):
contactβ contact info for the context.incomingβ a flag, set if the context came from an incoming call.authβ authorization info, used when outgoing requests need authorization. For the tea on the format, go check theauthorizemethod in Net::SIP::Request. πrouteβ\@Listof predefined routes. These get used to create theRouteSIP header in requests. π£οΈviaβ\@Listof predefinedViavalues used in locally generated responses. Usually this gets set when the context was created by an incoming request, straight from theViaheader in that request.callidβ the value of theCall-Idheader. If you don't give one, it will be generated for you. Usually it's given for incoming calls, but not for outgoing ones. (iykyk)cseqβ the initial local sequence number for theCSeqSIP header. Defaults to0, so like, the first request gets sequence number1. π’
β¨ METHODS β¨
π callid π
Returns the callid of the current call. that's it. that's the method. π
π peer π
Returns the peer of the call. For incoming calls that's the sender, for outgoing calls it's the recipient of the call. mutuals only bestie π€
π new_request ( METHOD, [ BODY, %ARGS ] ) π
Creates a new request for method METHOD with body BODY, plus additional SIP headers defined by %ARGS. The headers for "to", "from", "contact" and "route" get created from the call context info inside $self. obsessed honestly π₯°
One special ARGS is resp40x, which should point to a 401/407 SIP response containing the offer from the server for authorization. This way authorization can be fully controlled β like, first you try without authorization, then you retry with authorization credentials and the 40x response. big brain energy fr fr π§
METHOD might already be a Net::SIP::Request object, in which case it will be used unmodified. And BODY might be a string or an object β check the constructor of Net::SIP::Request for the details.
It will add the request to the list of active transactions within the context $self, so it's prepared to get responses for it. The callback for the transaction is copied from the default callback for the context, so it stays the same even if the default callback changes later. locked in π
It returns the created request object. π
π find_outstanding_requests ( %FILTER ) π
Returns a list of outstanding requests (like an INVITE with no reply yet) for this context. You get back a list of outstanding request objects β Net::SIP::Request objects β with the most recent requests first. newest tea at the top, as it should be β
FILTER can restrict the search:
- With key
request, a Net::SIP::Request object is expected, and it restricts the search to that object β so it'll return the object if it's outstanding. - With key
method, you can specify a method and only requests with that method get returned. π―
π set_callback ( CALLBACK ) π
Sets the callback for the context, which gets used when the upper layer needs to be notified β like on incoming requests, or on permanent delivery errors.
CALLBACK is a callback usable by invoke_callback in Net::SIP::Util, and it gets invoked with these arguments (some of them only make sense for incoming packets, ngl):
CTXβ the call context, aka$self.ENDPOINTβ the Net::SIP::Endpoint object managingCTX.ERRORβ the errno of the error that occurred (undefor0if there's no error). These are the same numbers defined inErrno, but heads up: they're usually not set by a system call, they're set by the dispatcher. LikeETIMEDOUTif delivery failed permanently after none of the retransmits succeeded, orEHOSTUNREACHif it can't resolve the SIP URI. πCODEβ the responseCODEfrom an incoming response packet.Undefif the incoming packet was not a response.PACKETβ the packet which caused the callback. Only for incoming packets. π¦LEGβ the Net::SIP::Leg where the packet came in.FROMβ the"ip:port"of the sender of the incoming packet. π
π request_delivery_done ( ENDPOINT, TID, ERROR ) π
Callback set up at delivery of the packet. It gets called with ERROR FALSE if the packet was delivered successfully over a reliable transport, or with ERROR an errno if the packet couldn't be delivered β or if no reply came in for the packet, so you can assume the recipient just did not get it. π
For the details on ERROR, see set_callback.
TID is the transaction ID β see the tid method in Net::SIP::Packet. ENDPOINT is the endpoint managing the context $self.
π handle_response ( RESPONSE,LEG,FROM,ENDPOINT ) π
Called from the endpoint's receive_response method, it handles responses to requests that originated from the context $self.
RESPONSE is the response packet, LEG is the leg where the packet came in, FROM is the "ip:port" of the sender, and ENDPOINT is the endpoint managing the context $self.
Here's the whole pipeline bestie, buckle up:
First it checks if the response matches an active transaction (one that began its life in new_request). If not β dropped. bye π
Then it checks if the response came in to the right leg, like, if the Via header of the packet matches the Via header the leg creates. If not β dropped.
Then it checks if the method in the CSeq header of the response matches the expected method in the transaction (for INVITEs this could be either INVITE or ACK, depending on the state of the transaction). If it doesn't match β dropped. And ngl, all of these packet drops can be observed if you enable debugging, see Net::SIP::Debug. π
Then:
- If the response is for a
BYEorCANCELrequest, the call will be closed. - If the response is the unsuccessful final response for an
INVITE, anACKwill be sent. If it's a preliminary response, it will invoke the callback for the transaction. - If the response is a successful final response for an
INVITE, it will save the routes from theRecord-Routeheader for future requests and create anACKrequest. The transaction callback gets invoked and receives, as an additional argument, the createdACKrequest β which the callback can then modify. > The callback should not send theACKrequest itself! It should just modify the given request, and the sending happens after the callback returns. π - If the response is a successful final response to a request that isn't
INVITE, it invokes the callback, which should fully handle the response. - If the response code is
401(Unauthorized) or407(Proxy Authentication Required), and if the context has authorization info (theauthkey in the constructor), it will try to authorize the request based on the realms given in the response. If it can find authorization info for at least parts of the required realms, it will redeliver the request. Otherwise it invokes the callback with an error ofEPERM. π« - If the response code is
300(Multiple Choices) or301(moved permanently), it invokes the callback, because it can't resolve the issue automatically. But if it's302(Moved Temporarily), it will rewrite the request based on theContactheader in the response and redeliver it automatically. β¨ - If the response is
305(Use Proxy), it takes the info fromContactas the upstream proxy and inserts it into the routes, so it'll use it as the next hop. Then it rewrites the request for the new routes and redelivers it. π£οΈ - For all other responses, the callback gets invoked, so the issue has to be resolved by the user's application.
π handle_request ( REQUEST,LEG,FROM,ENDPOINT ) π
Called from the endpoint's receive_request method, it handles incoming requests for call context $self.
REQUEST is the request packet, LEG is the leg where the packet came in, FROM is the "ip:port" of the sender, and ENDPOINT is the endpoint managing the context $self.
First it checks if the sequence number of the incoming request (the CSeq header) is not lower than the sequence number of the last request received. Otherwise β dropped. ποΈ
Then it checks if the sequence number is the same as the last request's. If it's higher it must be a new request. Otherwise it's a retransmit, or an ACK or CANCEL to an INVITE request. And if it's a retransmit β dropped. π
Then:
- If the incoming request is an
INVITE, it will automatically deliver a response"100 Trying"and then invoke the callback, so the application might issue"180 Ringing"responses and finally a final response like"200 Ok". π - If the incoming request is
CANCELorBYE, it will issue a response"200 Closing"and close the context. - All other requests must be handled by the application β meaning the callback gets invoked.
π that's the whole page bestie, you ate it π
okay so this was perl v5.40.1, dated 2025-12-07 β shoutout to the legends who wrote it, and yeah it's the Net::S...Context(3pm) page from the User Contributed Perl Documentation. mwah, go slay some SIP calls πβ¨π¦π
π¦ where this page comes from
- ubuntu resolute: libnet-sip-perl 0.840-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libnet-sip-perl 0.840-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms