Net::S...r::Base(3pm)

πŸ’– Net::SIP::NATHelper::Base πŸ’–

okay so bestie, welcome to your 3pm manual page β€” it's from the User Contributed Perl Documentation collection, and it's about the module Net::SIP::NATHelper::Base, which is genuinely the backstage crew making NAT work behind the scenes. let's get into it 🫢


✨ NAME ✨

Net::SIP::NATHelper::Base β€” rewrite SDP and transport RTP for NAT πŸ¦‹


🌸 DESCRIPTION 🌸

This module helps with doing NAT. it's not out here begging for attention either β€” it gets used implicitly inside do_nat from Net::SIP::StatelessProxy. iykyk.

What it actually cares about, like its whole personality:

  • rewriting the SDP bodies ✍️
  • forwarding RTP data for active sessions πŸ“¦
  • expiring sessions ⏰

πŸŽ€ CONSTRUCTOR πŸŽ€

new ( %ARGS )

Creates a new object, periodt. %ARGS can be:

  • max_sockets N β€” restricts the max number of sockets allocated inside the object to N. keep it cute, keep it capped πŸ’…
  • max_sockets_in_group N β€” restricts the max number of sockets allocated for a single socket group (like, a single call to get_rtp_sockets) to N.

πŸ‘‘ METHODS πŸ‘‘

allocate_sockets ( NAT_BASIC,SIDE,ADDR,MEDIA )

This is the one you call to allocate new local sockets for MEDIA. MEDIA is a \@list of specifications, exactly the kind you get from get_media in Net::SIP::SDP. ADDR is the local address where the sockets should be allocated. 🏠

NAT_BASIC consists of:

[ CALLID, CSEQ, IDFROM, IDTO, URI_FROM, URI_TO ]

IDFROM and IDTO represent the sides of the session, while SIDE helps pick the right side for allocation β€” e.g. if SIDE is 0 the sockets get allocated on the IDFROM side, and if it's 1 it's the IDTO side. so for Requests SIDE is 0, and for responses it's 1. 🌈

CALLID and CSEQ are used to identify the SIP transaction that the NAT is being done for, while IDSIDE is either IDFROM or IDTO (see below) depending on the side where the packet came in.

URI_FROM and URI_TO are primarily for information. πŸ“

The method returns the \@list of new media in the format needed by replace_media_listen in Net::SIP::SDP β€” like, tuples of:

[ip,base_port]

If allocating the sockets fails (resource constraints, ugh 😭) it returns undef. That usually means the caller just... doesn't forward the packet and waits for the retransmit (at least for UDP). no cap.


activate_session ( NAT_BASIC ,[\%PARAM] )

NAT_BASIC is exactly as described in allocate_sockets. This activates a session in the transaction defined by CALLID, CSEQ. And heads up β€” this will cause all sessions for older transactions in the same call (identified by CALLID) to shut down. dramatic, but necessary πŸ’€

IDFROM and IDTO represent the sides of the session, so for the activation to succeed there had to be an allocate_sockets call for each of these sides.

PARAM is an optional hash reference. If you give it, it gets added as user information to the new session and handed back in the information hash returned by close_session etc. URI_FROM and URI_TO get added to PARAM as uri_from and uri_to. 🎁

The method returns two items:

  1. information about the session, like what's returned in close_session
  2. a flag, which is true if the activation was for an already established session

Usually called whenever a SDP body shows up, and on ACK requests. πŸ“¬


close_session ( NAT_BASIC )

NAT_BASIC is as described before.

This causes the close of the session described by the arguments (which mean the same thing as in activate_session). Usually called for BYE or CANCEL requests. For CANCEL it's called with CSEQ (because it should cancel a specific transaction), while for BYE it's called with CSEQ undef, because it should end all sessions in this call. πŸ’…

It returns a list with infos about all closed sessions. Each of these infos is a reference to a hash with these items:

  • callid
  • cseq
  • idfrom
  • idto
  • bytes_from β€” number of bytes received on the 'from' side
  • bytes_to β€” number of bytes received on the 'to' side
  • from β€” space delimited list of ip:port/range for the media on the 'from' side
  • to β€” same for the 'to' side
  • created β€” time_t when the session was created
Stateless proxies should forward the packet even if the session did not exist, because the packet might be a retransmit referring to an already closed session. fr fr, don't drop it πŸ™ˆ

expire ( [ %ARGS ] )

This causes the sessions and sockets to expire. ⏰✨ It returns a list with a hash for each expired session β€” see close_session for the details on the returned information.

With %ARGS the behavior can be customized:

  • time β€” current time, can be given to save a system call for getting the current time
  • unused β€” expire time for unused sockets. Default is 180, e.g. 3 minutes
  • active β€” expire time for active sessions. Default is 30 seconds. If no data gets transferred through the session for active seconds, the session will be closed
  • closed β€” expire time for closed sessions, i.e. the time after which the sockets from a closed (replaced) session will be closed too. They're usually kept open a short time in case packets are still in transit. Default is 1 second

callbacks

This returns a list (not a reference, bestie, a list) of [cbid,fd,callback] pairs, where fd is the file descriptor of the socket and callback is a callback for invoke_callback in Net::SIP::Util. cbid is a uniq id for each callback so you can compare the result from different calls to callbacks and see what changed. πŸ”

Each of these callbacks should be invoked once the file descriptor gets readable, and the callback will then forward the received packet to the other side of the session. πŸ“¨


sessions ( [ CALLBACK ] )

This calls CALLBACK on all sessions and returns an array containing the results of the callbacks all together. If no CALLBACK is given it returns all session objects. 🫢

To use this function you might need to know the interna of the session objects (see source code πŸ“–), but in most cases it's enough to know that session objects have a method info_as_hash which returns infos about the session as a hash, just like described in close_session.


get_rtp_sockets ( NEW_ADDR, @MEDIA )

Allocates sockets on address NEW_ADDR for @MEDIA. @MEDIA is in the format given by get_media in Net::SIP::SDP. 🎧

Returns a reference to an array of allocated media, each item in the array being:

[ ADDR,BASE_PORT,\@SOCKS,\@TARGETS ]

where ADDR is NEW_ADDR, BASE_PORT is the base port for the allocated sockets, @SOCKS are the allocated sockets, and @TARGETS is the sockaddr of the original targets β€” i.e. where it needs to forward the data received on the sockets. 🎯

If not all necessary sockets could be allocated, it will allocate none and return ().

This method might be redefined to better control resource allocation, or to cache temporally unused resources together with unget_rtp_sockets. πŸ’œ


unget_rtp_sockets ( NEW_MEDIA )

Will take resources back. NEW_MEDIA is the result from get_rtp_sockets. Returns nothing. πŸ«₯

Together with get_rtp_sockets it could be redefined to not destroy resources but to cache them for future use. 🌈


dump

This method is used for debugging only. It returns a string with information about all calls within this nathelper, and all sessions and allocated sockets within the calls. πŸ•΅οΈβ™€οΈ


number_of_calls

Returns the number of calls within the nathelper. This value has not much association with the result of callbacks because there might be inactive sockets (not yet or no longer in active session) which don't affect the result of callbacks. πŸ™ƒ

This value can be used to determine if expire needs to be called at all.


πŸ’Œ and that's the whole page, bestie!! this was perl v5.40.1, dated 2025-12-07, from the User Contributed Perl Documentation ✨ go forth and NAT responsibly πŸ’…πŸŽ€πŸ¦‹
πŸ“¦ where this page comes from