RTPPROXY(8)
πΈ RTPPROXY π β the rtpproxy(8) glow-up
okay bestie, sit down, hydrate, because we're talking about rtpproxy β the RTP (Real-time Transport Protocol) Proxy Server. yes it's section 8, yes it's a daemon, yes it's iconic. π
β¨ NAME β¨
rtpproxy β RTP (Real-time Transport Protocol) Proxy Server π¦
β¨ SYNOPSIS β¨
rtpproxy [-?] [-2] [-f] [-v] [-V] [-R] [-l addr1[/addr2]...]
[-l [label@]address[=advertized_address]...]
[-6 addr1[/addr2]...]
[-6 [label@]address[=advertized_address]...] [-s ctrl_socket]
[-t tos] [-p pidfile] [-T max_ttl] [-r rdir [-S sdir]]
[-L nofile_limit] [-A advaddr1[/advaddr2]] [-m min_port]
[-M max_port] [-u uname[:gname]] [-w sock_mode] [-F] [-i]
[-n timeout_socket] [-P] [-a] [-d log_level[:log_facility]]
[-W setup_ttl] [--force_asymmetric]
look at all those flags, it's giving main character energy, no cap. π
β¨ DESCRIPTION β¨
so here's the tea. rtpproxy is a generic-purpose RTP proxy server, and it was literally designed to be used in conjunction with a SIP Controller that's capable of rewriting SDP contents. OpenSIPS, Kamailio, and Sippy B2BUA all support rtpproxy β like, the whole friend group showed up. π«Ά
and why do we care? Because rtpproxy can be used to facilitate RTP sessions between SIP user agents that are sitting behind a NAT(s) (Network Address Translator) firewall. π§± Several cases exist when direct end-to-end communication is not possible and RTP streams have to be relayed through another host. And that's literally the job: rtpproxy can be used to set up such a relaying host. π
π¦ Bridging mode, aka the glow-up
The rtpproxy can also operate as an application level bridge by specifying two interfaces to listen on. In bridging mode, rtpproxy forwards RTP packets received on one interface to the other interface, and vice versa. π
This mode can be used to forward RTP packets between networks without direct network level connectivity β provided that the host running rtpproxy has an interface connected to both networks. iykyk. And one particular application of bridging mode? IPv4/IPv6 traversal of RTP packets. πβ¨
π Recording, forking, and playing files
When instructed by the call controller, rtpproxy will:
- record the entire RTP session to the local hard disk πΎ
- fork-off (copy) to a remote server π€
- and/or play a pre-recorded file to the user agent
and the use cases? comfort ring replacement, Music-on-Hold, disclaimer announcements etc. π΅ disclaimer announcements are so real, bestie.
β Metrics, because we love data
The rtpproxy tracks various important operational metrics about RTP sessions (calls), such as the number of packets:
- sent
- received
- lost
- forwarded
and so forth. π Real-time metrics can then be retrieved by issuing the appropriate command via the control socket interface. obsessed with a server that knows its own stats. π₯
β οΈ heads up: this is part 1 of 3, so don't go anywhere β the options are coming and there are a lot of them. π«Ά
β¨ OPTIONS β¨
Okay so bestie, grab ur matcha π΅ because this is the options menu and it's long. Every flag, every default, every little warning β we're covering it all. No skips. Periodt. Slay. π
-?β shows a summary of options. Like a lil cheat sheet, yk? π-2β sends every RTP packet twice in sessions that use low-bitrate codecs. Only packets smaller than128bytes get sent twice. This can improve audio quality on lossy links. β¨-fβ makesrtpproxystay in foreground mode if this option is set. No daemon ghosting u. π»-Vβ show version of program. π-vβ show supportedrtppcommand protocol revisions. π-l addr1[/addr2]β IPv4 listen IP address(es). This option can be specified multiple times. Bridging mode can be enabled when the first IPv4 (or first IPv6) listen argument is specified asaddr1/addr2. Additional labeled listen addresses use the separate format[label@]address[=advertized_address]. The/addr2form is not valid for labeled entries. When multiple listen addresses are configured, all addresses after the first must have unique labels. Such labels are accepted by thel{label}argument inUandLcommands.-6 addr1[/addr2]β IPv6 listen IP address(es). This option can be specified multiple times. Two argument formats are supported:addr1[/addr2]and[label@]address[=advertized_address].-s ctrl_socketβ this parameter configuresrtpproxycontrol socket. The control socket is used by the call controller for the purpose of creating, modifying, and deleting RTP sessions. The control socket can also be used to fetch stats from thertpproxyprocess, or about specific media sessions. Format ofctrl_socketis<type>:<socket>. Following types are supported:udp:β create UDP control socket. In this modertpproxywill listen on a UDP socket for control messages from the call controller. Example:-s udp:127.0.0.1:9000IP address can be'*'in which casertpproxywill listen on all local interfaces. If port is omitted then port22222will be used.
β οΈ Note:rtpproxycontrol protocol has no built-in security mechanisms. Make sure that you protect the listening IP and port properly when usingrtpproxywith UDP control socket. π
udp6:β create IPv6 UDP control socket. In this modertpproxywill listen on UDP/IPv6 for control messages from the SIP Controller. Example:-s udp6:::1:9000tcp:β create IPv4 TCP control socket. In this modertpproxywill listen on TCP/IPv4 for control messages from the SIP Controller. Example:-s tcp:192.168.0.1:9001tcp6:β create IPv6 TCP control socket. In this modertpproxywill listen on TCP/IPv6 for control messages from the SIP Controller. Example:-s tcp6:::1:9002unix:β create UNIX domain socket in a datagram-like mode for control interface. In this mode the SIP Controller andrtpproxymust be running on the same host. This is traditional mode whenrtpproxywould close connection after processing each command and sending reply. Example:-s unix:/var/run/rtpproxy.sockcunix:β create UNIX domain socket for control interface. In this mode the SIP Controller andrtpproxymust be running on the same host. Similar tounix:above, but thertpproxywould keep control socket open and accept multiple commands via the same connection. Example:-s cunix:/var/run/rtpproxy.sockDefault value isunix:/var/run/rtpproxy.sock.
-t tosβ set ToS (Type of Service) in the outgoing IP header. Default value is0xB8. Setting this parameter to-1disables setting ToS resulting in operating system default ToS being used instead. π°οΈ-r rec_dirβ directory to write recorded RTP sessions. πΌ-S spool_dirβ spool directory for recording of RTP streams. When the session is stopped, the recording will be moved from the spool directory to therec_dirdirectory as specified by the-roption. ποΈ-Rβ preventrtpproxyfrom recording RTCP when recording RTP.rtpproxyrecords RTCP by default when RTP recording is enabled. π«-p pid_fileβ this parameter configures the name of the file where PID of runningrtpproxywill be stored. Default is/var/run/rtpproxy.pid. π-T max_ttlβ specify the RTP inactivity timer. Defaults to60seconds. If thertpproxydoes not receive any RTP packets for more thanmax_ttlit will then delete the session. β³-L nofile_limitβ set the maximum number of open file descriptors per process. The default maximum is set by the operating system, and can be overridden using the-Lflag. Thertpproxyrequires four file descriptors per session to ensure that it can reliably identify where each stream is coming from in a NAT firewall scenario. π’-A advaddr1[/advaddr2]β set advertised address ofrtpproxy. Useful if thertpproxyis behind a NAT firewall. (Amazon EC2) When thertpproxyreceives a session request from a SIP controller it will return the IP address(es) specified by the-Aoption. This option configures the legacy bridge internal/external address pair. For per-address advertised overrides with multiple-l/-6entries, use=advertized_addressinside each listen address argument. βοΈ-m min_portβ set lower limit on UDP ports range that thertpproxyuses for RTP/RTCP sessions tomin_port. Default is35000. β¬οΈ-M max_portβ set upper limit on UDP ports range that thertpproxyuses for RTP/RTCP sessions tomax_port. Default is65000. β¬οΈ-u uname[:gname]β switchrtpproxyto UID identified by theunameand optional GID identified bygnamewhen proxy is up and running. π€-w sock_modeβ set access mode for the controlling UNIX-socket (if used). Only applies ifrtpproxyruns under a different GID using-uoption. π-Fβ by default thertpproxywill warn user if running as superuser (UID0) in local control mode and refuse to run in remote control mode at all. This switch removes the check. β οΈ-iβ enable independent RTP activity timeout mode. By default, a timeout (which results in automatic destruction of the session) can only occur if no RTP packets are received on any of the session's ports. This option, if set, varies that behaviour, such that a timeout will occur if packets are still being received on one port but not the other. The option should be used with caution since in some cases it's perfectly fine to have packets coming from only one side of conversation (i.e. when the second party has muted its audio). π-n timeout_socketβ this parameter specifies permitted notification sockets only. The listening socket must be created by another application, preferably before startingrtpproxy. Timeout notifications must be enabled by the SIP controller when setting up the session. The SIP Controller must specify thetimeout_socket, and anotify_tag, which is expected to be an arbitrary string that can be used by the SIP controller to identify which session a received time out notification relates to. If a SIP Controller specifies a notification socket for a session, and that socket is not specified using the-nflag, thertpproxywill not send a notification, and will not produce an error. It will ignore the notification request. Format oftimeout_socketis<type>:<socket>. Following types are supported:unix:β connect to UNIX domain socket for sending timeout notifications. In this mode B2BUA andrtpproxymust be running on the same host. Example:-n unix:/var/run/rtpproxy_timeout.socktcp:β connect to a remote host using TCP/IP for sending timeout notifications. Format of the socket parameter in this case is<host>:<port>. Example:-n tcp:10.20.30:12345There is no default value, notifications are not sent and not permitted unless a value is specified explicitly. Multiple notification sockets can be provided by specifying the-nflag more than once. π
-Pβ record sessions using libpcap file format instead of non-standard ad-hoc format. The libpcap format, which is the de-facto standard for packet capturing software, has the advantage of being compatible with numerous third-party tools and utilities, such astcpdumpor Wireshark. The drawback of libpcap is slightly larger overhead (extra12bytes for every saved RTP packet for IPv4). π¦-aβ record all sessions going through thertpproxyunconditionally. By defaultrtpproxyexpects the SIP controller to enable recording on a per-session basis. π₯-d log_level[:log_facility]β configures the verbosity level of the log output. Possiblelog_levelvalues in the order from the most verbose to the least verbose are:DBUG,INFO,WARN,ERRandCRIT. The optionallog_facilityparameter setssyslog(3)facility assigned to log messages. Example:-d WARN:LOG_LOCAL5The default level in foreground mode isDBUG, in background -WARNand facility isLOG_DAEMON. π--force_asymmetricβ treat all RTP/RTCP sessions as"assymetric", i.e. disable any NAT traversal features unconditionally. π«
π« PRINCIPLES OF OPERATION π«
Okay bestie, here's the whole plot arc, step by step, no skips. π¬
When the SIP controller gets an INVITE request, it pulls the Call-ID and from_tag out of that INVITE. Then the call controller passes those over to the rtpproxy, either through a Unix domain socket or a UDP socket. The rtpproxy goes looking for an existing session that matches the Call-ID and from_tag it just got handed.
If the rtpproxy finds a session that's already associated with that Call-ID, it just returns the UDP port number that's already tied to that session. Easy, no new port, we're reusing, we're sustainable. β»οΈ
But if that Call-ID and from_tag combo isn't attached to any existing session yet, the rtpproxy spins up a brand-new session by randomly picking a free UDP port out of the usable UDP port range. That UDP port number gets handed back as the response to the SIP controller's request. β¨
Then the SIP controller is supposed to rewrite the SDP, swapping the ip:port for the IP address of the rtpproxy plus the port number the rtpproxy just allocated. The user agent reading that SDP will then send its RTP stream straight to the rtpproxy. it's giving middleman, and honestly? iconic. π«Ά
Now β when the SIP Controller receives a non-negative SIP reply that has SDP in it, it pulls the Call-ID, from_tag and to_tag out of the SIP message and sends a request over to the rtpproxy with Call-ID, from_tag and to_tag.
The rtpproxy hunts for an existing session based on the Call-ID and from_tag, which β plot twist β it should find. Then it randomly chooses another port and "connects" this port with the earlier allocated port, forming the proxy between both sides. Two ports, one bridge, we're connected bestie. π
Once the SIP controller gets that new port number back from the rtpproxy, it's expected to rewrite the SDP inside the SIP message body, replacing the ip:port with the IP address and the new udp port number that the rtpproxy provided. And the SIP controller is expected to send that reply along to the user agent that kicked off the call in the first place. π¨
After the session's been created, the proxy just sits there listening on the ports it allocated for that session, waiting to receive at least one UDP packet from each of the two parties in the call. The moment a packet shows up, the proxy fills one of the two IP:port structures associated with the respective stream with the source IP:port of that packet. And when both structures are filled in, the proxy starts relaying UDP packets between the parties. the way that it waits for both sides before saying a single word? that's boundaries. π
Last thing: the rtpproxy tracks idle time for each of its existing sessions (that's the time interval during which no packets got relayed), and it automatically cleans up sessions whose idle times exceed the idle time β which is 60 seconds by default. gone, ghosted, blocked. π
π FILES π
rtpproxymakeannextractaudio
π LICENSE π
Every single component of the rtpproxy is licensed under the BSD 2-Clause License. Wanna read the fine print? See the LICENSE file at the top of the source tree for the details. π
π AVAILABILITY π
The freshest, most up-to-date version of this program and all its components lives at http://www.rtpproxy.org/. go get it, bestie. ποΈ
π AUTHORS π
- Jan Janak
<janakj@users.berlios.de>- Author.
- Maksym Sobolyev
<sobomax@sippysoft.com>- Author.
π COPYRIGHT π
Copyright Β© 2006-2026 Maksym Sobolyev <sobomax@sippysoft.com>
Copyright Β© 2006 Jan Janak <janakj@users.berlios.de>
And that's the whole page, babe β this one's [FIXME: source], dated May 16, 2019, and it's RTPPROXY(8) through and through. no cap, you understood all of it. slay. ππβ¨
π¦ where this page comes from
- fedora 43: rtpproxy 3.2.0-3.fc43 Β· BSD-2-Clause
- fedora 44: rtpproxy 3.2.0-3.fc44 Β· BSD-2-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms