RTPENGINE(1) | NGCP rtpengine | RTPENGINE(1) |
rtpengine - NGCP proxy for RTP and other UDP based media traffic
rtpengine --interface=addr... --listen-tcp|--listen-udp|--listen-ng|--listen-tcp-ng|--listen-http|--listen-https=addr... [option...]
The Sipwise NGCP rtpengine is a proxy for RTP traffic and other UDP based media traffic. It is meant to be used with the Kamailio SIP proxy and forms a drop-in replacement for any of the other available RTP and media proxies.
Most of these options are indeed optional, with two exceptions. It's mandatory to specify at least one local IP address through --interface, and at least one of the --listen-... options must be given.
All options can (and should) be provided in a config file instead of at the command line. See the --config-file option below for details.
As a special value, none can be passed here to suppress loading of the default config file.
In this case, ICE will be broken.
The tcp protocol is obsolete. It was used by old versions of OpenSER and its mediaproxy module. It is provided for backwards compatibility.
The udp protocol is used by Kamailio's rtpproxy module. In this mode, rtpengine can be used as a drop-in replacement for any other compatible RTP proxy.
The ng protocol is an advanced control protocol and can be used with Kamailio's rtpengine module. With this protocol, the complete SDP body is passed to rtpengine, rewritten and passed back to Kamailio. Several additional features are available with this protocol, such as ICE handling, SRTP bridging, etc.
The tcp-ng protocol is in fact the ng protocol but transported over TCP.
It is recommended to specify not only a local port number, but also 127.0.0.1 as interface to bind to.
The log levels correspond to the ones found in the syslog(3) man page. The default value is 6, equivalent to LOG_INFO. The highest possible value is 7 (LOG_DEBUG) which will log everything.
During runtime, the log level can be decreased by sending the signal SIGURS1 to the daemon and can be increased with the signal SIGUSR2.
The full list of logging subsystems can be viewed by pulling up the --help online help. Some (if not all) subsystems are: core, spandsp (messages generated by SpanDSP itself), ffmpeg (messages generated by ffmpeg libraries themselves), transcoding (messages related to RTP/media transcoding), codec (messages related to codec negotiation), rtcp, ice, crypto (messages related to crypto/SRTP/SDES/DTLS negotiation), srtp (messages related to RTP/SRTP en/decryption), internals (disabled by default), http (includes WebSocket), control (messages related to control protocols, including SDP exchanges).
Media playback is actually handled by two threads: One for reading and decoding the media file, and another to schedule and send out RTP packets. So for example, if this option is set to 4, in total 8 threads will be launched.
If the Redis database is protected with an authentication password, the password can be supplied by prefixing the argument value with the password, separated by an @ symbol, for example foobar@127.0.0.1:6379/12. Note that this leaves the password visible in the process list, posing a security risk if untrusted users access the same system. As an alternative, the password can also be supplied in the shell environment through the environment variable RTPENGINE_REDIS_AUTH_PW.
On startup, rtpengine will read the contents of this database and restore all calls stored therein. During runtime operation, rtpengine will continually update the database's contents to keep it current, so that in case of a service disruption, the last state can be restored upon a restart.
When this option is given, rtpengine will delay startup until the Redis database adopts the master role (but see below).
For password protected Redis servers, the environment variable for the password is RTPENGINE_REDIS_WRITE_AUTH_PW.
When both options are given, rtpengine will start and use the Redis database regardless of the database's role (master or slave).
Be aware that if the -r redis cannot be initially connected, sessions are not reloaded upon rtpengine startup, even though rtpengine still starts.
rtpengine supports multiple mechanisms for recording calls. See recording-method below for a list. The default recording method pcap is described in this section.
PCAP files will be stored within a pcap subdirectory and metadata within a metadata subdirectory.
The format for a metadata file is (with a trailing newline):
/path/to/recording-pcap.pcap SDP mode: offer SDP before RTP packet: 1 first SDP SDP mode: answer SDP before RTP packet: 1 second SDP ... SDP mode: answer SDP before RTP packet: 100 n-th and final SDP start timestamp (YYYY-MM-DDThh:mm:ss) end timestamp (YYYY-MM-DDThh:mm:ss) generic metadata
There are two empty lines between each logic block of metadata. We write out all answer SDP, each separated from one another by one empty line. The generic metadata at the end can be any length with any number of lines. Metadata files will appear in the subdirectory when the call completes. PCAP files will be written to the subdirectory as the call is being recorded.
Since call recording via this method happens entirely in userspace, in-kernel packet forwarding cannot be used for calls that are currently being recorded and packet forwarding will thus be done in userspace only.
The recording method proc works by writing metadata files directly into the recording-dir (i.e. not into a subdirectory) and instead of recording RTP packet data into pcap files, the packet data is exposed via a special interface in the /proc filesystem. Packets must then be retrieved from this interface by a dedicated userspace component (usually a daemon such as recording-daemon included in this repository).
Packet data is held in kernel memory until retrieved by the userspace component, but only a limited number of packets (default 10) per media stream. If packets are not retrieved in time, they will be simply discarded. This makes it possible to flag all calls to be recorded and then leave it to the userspace component to decided whether to use the packet data for any purpose or not.
In-kernel packet forwarding is fully supported with this recording method even for calls being recorded.
This option allows creating a firewall with a default DROP policy for the entire port range used by rtpengine and then referencing the given iptables chain to only selectively allow the ports actually in use.
Note that this applies only to media ports, and does not apply to any other ports (such as the control ports) used by rtpengine.
Also note that the iptables API is not the most efficient one around and does not lend itself to fast dynamic creation and deletion of rules. If you have a high call volume, and especially many call attempts per second, you might experience significant performance impact. This is not a shortcoming of rtpengine but rather of iptables and its API implementation in the Linux kernel. In such a case, it is recommended to add a static iptables rule for the entire media port range instead, and not use this option.
The scheduling settings take the name of one of the supported scheduler policies. Setting it to default or none is equivalent to not setting the option at all and leaves the system default in place. The strings fifo and rr refer to realtime scheduling policies. other is the Linux default scheduling policy. batch is similar to other except for a small wake-up scheduling penalty. idle is an extremely low priority scheduling policy. The Linux-specific deadline policy is not supported by rtpengine. Not all systems necessarily supports all scheduling policies; refer to your system's sched(7) man page for details.
The priority settings correspond to the scheduling priority for realtime (fifo or rr) scheduling policies and must be in the range of 1 (low) through 99 (high). For all other scheduling policies (including no policy specified), the priority settings correspond to the nice value and should be in the range of -20 (high) through 19 (low). Not all systems support thread-specific nice values; on such a system, using these settings might have unexpected results. (Linux does support thread-specific nice values.) Refer to your system's sched(7) man page.
An example configuration might look like this:
mysql-query = select data from voip.files where id = %llu
The HTTP listener supports both HTTP and WS, while the HTTPS listener supports both HTTPS and WSS.
If HTTPS/WSS is enabled, a certificate must also be provided using the options below.
The defaults are 10 packets and 100 milliseconds.
If this value is set to zero then no adjustments of the DTX timer will be made. Instead, in order to keep up with the flow of received RTP packets, packets will be dropped or additional DTX audio will be generated as needed.
This option is applicable to audio generated to fill in transmission gaps during a DTX event. The default setting is no value, which means silence will be generated to fill in DTX gaps.
If any CN parameters are configured, the parameters will be passed to an RFC 3389 CN decoder, and the generated comfort noise will be used to fill in DTX gaps.
If CN is selected here, the same DTX mechanism as other codecs use is used for AMR, which is to fill in DTX gaps with either silence or RFC 3389 comfort noise (see dtx-cn-params). This also affects processing of received SID frames: SID frames would not be passed to the codec but instead be replaced by generated silence or comfort noise.
When enabled, silence detection will be performed on all transcoded audio streams. The threshold specified here is the sensitivity for detecting silence: higher thresholds result in more audio to be detected as silence, while lower thresholds result in less audio to be detected as silence. The threshold is specified as percent between zero and 100. If set to 100, then all audio would be detected as silence; if set to 50, then any audio that is quieter than 50% of the maximum volume would be detected as silence; and so on. Setting it to zero disables silence detection. To only detect silence that is very near or equal to absolute silence, set this value to a low number such as 0.01. (For certain codecs such as PCMA, a higher minimum threshold is required to detect complete silence, as their compressed payloads don't decode to actual silence but instead have a residual DC offset. For PCMA the minimum value is 0.013.)
Audio that is detected as silence will be replaced by comfort noise as specified by the cn-payload option (see below). Currently this is applicable only to RTP peers that have advertised support for the CN RTP payload type, in which case the silence audio frames will be replaced by CN RTP frames.
The first CN payload value given is the noise level, specified as -dBov as per RFC 3389. This means that a noise level of zero corresponds to maximum volume, while higher numbers correspond to lower volumes. The highest allowable number is 127, corresponding to -127 dBov, which is near silence.
Subsequent CN payload values carry spectral information (reflection coefficients) as per RFC 3389. Allowable values for each coefficient are between 0 and 254. Specifying spectral information is optional and the number of coefficients listed (model order) is variable.
This option is applicable only to CN packets generated from the silence detection mechanism described above. The configured CN parameters are used directly as payload of CN packets sent by rtpengine.
The default values are 32 (-32 dBov) for the noise level and no spectral information.
The command-line options -i or --interface, or equivalently the interface config file option, specify local network interfaces for RTP. At least one must be given, but multiple can be specified. The format of the value is [NAME/]IP[!IP] with IP being either an IPv4 address, an IPv6 address, the name of a system network interface (such as eth0), a DNS host name (such as test.example.com), or any.
The possibility of configuring a network interface by name rather than by address should not be confused with the logical interface name used internally by rtpengine (as described below). The NAME token in the syntax above refers to the internal logical interface name, while the name of a system network interface is used in place of the first IP token in the syntax above. For example, to configure a logical network interface called int using all the addresses from the existing system network interface eth0, you would use the syntax int/eth0. (Unless omitted, the second IP token used for the advertised address must be an actual network address and cannot be an interface name.)
If DNS host names are used instead of addresses or interface names, the lookup will be done only once during daemon start-up.
The special keyword any can be used to listen on any and all available local interface addresses except from loopback devices. This keyword should only be given once in place of a more explicit interface configuration.
To configure multiple interfaces using the command-line options, simply present multiple -i or --interface options. When using the config file, only use a single interface line, but specify multiple values separated by semicolons (e.g. interface = internal/12.23.34.45;external/23.34.45.54).
If an interface option is given using a system interface name in place of a network address, and if multiple network address are found configured on that network interface, then rtpengine behaves as if multiple --interface options had been specified. For example, if interface eth0 exists with both addresses 192.168.1.120 and 2001:db8:85a3::7334 configured on it, and if the option --interface=ext/eth0 is given, then rtpengine would behave as if both options --interface=ext/192.168.1.120 and --interface=ext/2001:db8:85a3::7334 had been specified.
The second IP address after the exclamation point is optional and can be used if the address to advertise in outgoing SDP bodies should be different from the actual local address. This can be useful in certain cases, such as your SIP proxy being behind NAT. For example, --interface=10.65.76.2!192.0.2.4 means that 10.65.76.2 is the actual local address on the server, but outgoing SDP bodies should advertise 192.0.2.4 as the address that endpoints should talk to. Note that you may have to escape the exclamation point from your shell when using command-line options, e.g. using \!.
Giving an interface a name (separated from the address by a slash) is optional; if omitted, the name default is used. Names are useful to create logical interfaces which consist of one or more local addresses. It is then possible to instruct rtpengine to use particular interfaces when processing an SDP message, to use different local addresses when talking to different endpoints. The most common use case for this is to bridge between one or more private IP networks and the public internet.
For example, if clients coming from a private IP network must communicate their RTP with the local address 10.35.2.75, while clients coming from the public internet must communicate with your other local address 192.0.2.67, you could create one logical interface pub and a second one priv by using --interface=pub/192.0.2.67 --interface=priv/10.35.2.75. You can then use the direction option to tell rtpengine which local address to use for which endpoints (either pub or priv).
If multiple logical interfaces are configured, but the direction option is not given in a particular call, then the first interface given on the command line will be used.
It is possible to specify multiple addresses for the same logical interface (the same name). Most commonly this would be one IPv4 addrsess and one IPv6 address, for example: --interface=192.168.63.1 --interface=fe80::800:27ff:fe00:0. In this example, no interface name is given, therefore both addresses will be added to a logical interface named default. You would use the address family option to tell rtpengine which address to use in a particular case.
It is also possible to have multiple addresses of the same family in a logical network interface. In this case, the first address (of a particular family) given for an interface will be the primary address used by rtpengine for most purposes. Any additional addresses will be advertised as additional ICE candidates with increasingly lower priority. This is useful on multi-homed systems and allows endpoints to choose the best possible path to reach the RTP proxy. If ICE is not being used, then additional addresses will go unused, even though ports would still get allocated on those interfaces.
Another option is to give interface names in the format BASE:SUFFIX. This allows interfaces to be used in a round-robin fashion, useful for load-balancing the port ranges of multiple interfaces. For example, consider the following configuration: --interface=pub:1/192.0.2.67 --interface=pub:2/10.35.2.75. These two interfaces can still be referenced directly by name (e.g. direction=pub:1), but it is now also possible to reference only the base name (i.e. direction=pub). If the base name is used, one of the two interfaces is selected in a round-robin fashion, and only if the interface actually has enough open ports available. This makes it possible to effectively increase the number of available media ports across multiple IP addresses. There is no limit on how many interfaces can share the same base name.
It is possible to combine the BASE:SUFFIX notation with specifying multiple addresses for the same interface name. An advanced example could be (using config file notation, and omitting actual network addresses):
interface = pub:1/IPv4 pub:1/IPv4 pub:1/IPv6 pub:2/IPv4 pub:2/IPv6 pub:3/IPv6 pub:4/IPv4
In this example, when direction=pub is IPv4 is needed as a primary address, either pub:1, pub:2, or pub:4 might be selected. When pub:1 is selected, one IPv4 and one IPv6 address will be used as additional ICE alternatives. For pub:2, only one IPv6 is used as ICE alternative, and for pub:4 no alternatives would be used. When IPv6 is needed as a primary address, either pub:1, pub:2, or pub:3 might be selected. If at any given time not enough ports are available on any interface, it will not be selected by the round-robin algorithm.
It is possible to use the round-robin algorithm even if the direction is not given. If the first given interface has the BASE:SUFFIX format then the round-robin algorithm is used and will select interfaces with the same BASE name.
If you are not using the NG protocol but rather the legacy UDP protocol used by the rtpproxy module, the interfaces must be named internal and external corresponding to the i and e flags if you wish to use network bridging in this mode.
A typical command line (enabling both UDP and NG protocols) may look like:
rtpengine --table=0 --interface=10.64.73.31 --interface=2001:db8::4f3:3d \ --listen-udp=127.0.0.1:22222 --listen-ng=127.0.0.1:2223 --tos=184 \ --pidfile=/run/rtpengine.pid
2023-02-22 | 10.5.3.5-1 |