Table of Contents
List of Tables
List of Examples
disable
parametermediaproxy_socket
parametermediaproxy_timeout
parametersignaling_ip_avp
parametermedia_relay_avp
parameterice_candidate
parameterice_candidate_avp
parameterengage_media_proxy
functionuse_media_proxy
functionend_media_session
functionMediaproxy is an OpenSIPS module that is designed to allow automatic NAT traversal for the majority of existing SIP clients. This means that there will be no need to configure anything in particular on the NAT box to allow these clients to work behind NAT when using the mediaproxy module.
This NAT traversal solution operates by placing a media relay in the middle between 2 SIP user-agents. It mangles the SDP messages for both of them in a way that will make the parties talk with the relay while they think they talk directly with each other.
Mediaproxy consists of 2 components:
The OpenSIPS mediaproxy module
An external application called MediaProxy which employs a dispatcher and multiple distributed media relays. This is available from http://ag-projects.com/MediaProxy.html (version 2.0.0 or newer is required by this module).
The mediaproxy dispatcher runs on the same machine as OpenSIPS and its purpose is to select a media relay for a call. The media relay may run on the same machine as the dispatcher or on multiple remote hosts and its purpose is to forward the streams between the calling parties. To find out more about the architecture of MediaProxy please read the documentation that comes with it.
To be able to act as a relay between the 2 user agents, the machine(s) running the module/proxy server must have a public IP address.
OpenSIPS will ask the media relay to allocate as many ports as there are media streams in the SDP offer and answer. The media relay will send back to OpenSIPS the IP address and port(s) for them. Then OpenSIPS will replace the original contact IP and RTP ports from the SDP messages with the ones provided by the media relay. By doing this, both user agents will try to contact the media relay instead of communicating directly with each other. Once the user agents contact the media relay, it will record the addresses they came from and will know where to forward packets received from the other endpoint. This is needed because the address/port the NAT box will allocate for the media streams is not known before they actually leave the NAT box. However the address of the media relay is always known (being a public IP) so the 2 endpoints know where to connect. After they do so, the relay learns their addresses and can forward packets between them.
The SIP clients that will work transparently behind NAT when using mediaproxy, are the so-called symmetric clients. The symmetric clients have the particularity that use the same port to send and receive data. This must be true for both signaling and media for a client to work transparently with mediaproxy without any configuration on the NAT box.
make symmetric clients work behind NAT transparently, with no configuration needed on the client's NAT box.
have the ability to distribute RTP traffic on multiple media relays running on multiple hosts.
The following modules must be loaded before this module:
dialog module - if engage_media_proxy is used (see below the description of engage_media_proxy).
Boolean flag that specifies if mediaproxy should be disabled. This is useful when you want to use the same OpenSIPS configuration in two different context, one using mediaproxy, the other not. In the case mediaproxy is disabled, calls to its functions will have no effect, allowing you to use the same configuration without changes.
Default value is “0”.
It is the path to the filesystem socket where the mediaproxy dispatcher listens for commands from the module.
Default value is “/run/mediaproxy/dispatcher.sock”.
Example 1.2. Setting the mediaproxy_socket
parameter
... modparam("mediaproxy", "mediaproxy_socket", "/run/mediaproxy/dispatcher.sock") ...
How much time (in milliseconds) to wait for an answer from the mediaproxy dispatcher.
Default value is “500”.
Example 1.3. Setting the mediaproxy_timeout
parameter
... modparam("mediaproxy", "mediaproxy_timeout", 500) ...
Specification of the AVP which holds the IP address from where the SIP signaling originated. If this AVP is set it will be used to get the signaling IP address, else the source IP address from where the SIP message was received will be used. This AVP is meant to be used in cases where there are more than one proxy in the call setup path and the proxy that actually starts mediaproxy doesn't receive the SIP messages directly from the UA and it cannot determine the NAT IP address from where the signaling originated. In such a case attaching a SIP header at the first proxy and then copying that header's value into the signaling_ip_avp on the proxy that starts mediaproxy will allow it to get the correct NAT IP address from where the SIP signaling originated.
Default value is “$avp(signaling_ip)”.
Example 1.4. Setting the signaling_ip_avp
parameter
... modparam("mediaproxy", "signaling_ip_avp", "$avp(nat_ip)") ...
Specification of the AVP which holds an optional application defined media relay IP address of a particular media relay that is preferred to be used for the current call. If an IP address is written to this AVP before calling use_media_proxy(), it will be preferred by the dispatcher over the normal selection algorithm.
Default value is “$avp(media_relay)”.
Example 1.5. Setting the media_relay_avp
parameter
... modparam("mediaproxy", "media_relay_avp", "$avp(media_relay)") ...
Indicates the type of ICE candidate that will be added to the SDP. It can take 3 values: 'none', 'low-priority' or 'high-priority'. If 'none' is selected no candidate will be added to the SDP. If 'low-priority' is selected then a low priority candidate will be added and if 'high-priority' is selected a high priority one.
Default value is “none”.
Example 1.6. Setting the ice_candidate
parameter
... modparam("mediaproxy", "ice_candidate", "low-priority") ...
Specification of the AVP which holds the ICE candidate that will be inserted in the SDP. The value specified in this AVP will override the value in ice_candidate module parameter. Note that if use_media_proxy() and end_media_session() functions are being used, the AVP will not be available in the reply route unless you set onreply_avp_mode from the tm module to '1', and if the AVP is not set, the default value will be used.
Default value is “$avp(ice_candidate)”.
Example 1.7. Setting the ice_candidate_avp
parameter
... modparam("mediaproxy", "ice_candidate_avp", "$avp(ice_candidate)") ...
Trigger the use of MediaProxy for all the dialog requests and replies that have an SDP body. This needs to be called only once for the first INVITE in a dialog. After that it will use the dialog module to trace the dialog and automatically call use_media_proxy() on every request and reply that belongs to the dialog and has an SDP body. When the dialog ends it will also call automatically end_media_session(). All of these are called internally on dialog callbacks, so for this function to work, the dialog module must be loaded and configured.
This function is an advanced mechanism to use a media relay without having to manually call a function on each message that belongs to the dialog. However this method is less flexible, because once things were set in motion by calling this function on the first INVITE, it cannot be stopped, not even by calling end_media_session(). It will only stop when the dialog ends. Until then it will modify the SDP content of every in-dialog message to make it use a media relay. If one needs more control over the process, like starting to use mediaproxy only later in the failure route, or stopping to use mediaproxy in the failure route, then the use_media_proxy and end_media_session functions should be used, and manually called as appropriate. Using this function should NOT be mixed with either of use_media_proxy() or end_media_session().
This function can be used from REQUEST_ROUTE.
Example 1.8. Using the engage_media_proxy
function
... if (is_method("INVITE") && !has_totag()) { # We can also use a specific media relay if we need to #$avp(media_relay) = "1.2.3.4"; engage_media_proxy(); } ...
Will make a call to the dispatcher and replace the IPs and ports in the SDP body with the ones returned by the media relay for each supported media stream in the SDP body. This will force the media streams to be routed through the media relay. If a mix of supported and unsupported streams are present in the SDP, only the supported streams will be modified, while the unsupported streams will be left alone.
This function should NOT be mixed with engage_media_proxy().
This function has the following return codes:
+1 - successfully modified message (true value)
-1 - error in processing message (false value)
-2 - missing SDP body, nothing to process (false value)
This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
Example 1.9. Using the use_media_proxy
function
... if (is_method("INVITE")) { # We can also use a specific media relay if we need to #$avp(media_relay) = "1.2.3.4"; use_media_proxy(); } ...
Will call on the dispatcher to inform the media relay to end the media session. This is done when a call ends, to instruct the media relay to release the resources allocated to that call as well as to save logging information about the media session. Called on BYE, CANCEL or failures.
This function should NOT be mixed with engage_media_proxy().
This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
Example 1.10. Using the end_media_session
function
... if (is_method("BYE")) { end_media_session(); } ...
Table 2.1. Top contributors by DevScore(1), authored commits(2) and lines added/removed(3)
Name | DevScore | Commits | Lines ++ | Lines -- | |
---|---|---|---|---|---|
1. | Dan Pascu (@danpascu) | 130 | 55 | 4241 | 2404 |
2. | Bogdan-Andrei Iancu (@bogdan-iancu) | 39 | 31 | 688 | 88 |
3. | Saúl Ibarra Corretgé (@saghul) | 21 | 14 | 504 | 71 |
4. | Liviu Chircu (@liviuchircu) | 14 | 12 | 41 | 49 |
5. | Daniel-Constantin Mierla (@miconda) | 13 | 11 | 37 | 33 |
6. | Razvan Crainea (@razvancrainea) | 9 | 7 | 22 | 41 |
7. | Vlad Patrascu (@rvlad-patrascu) | 4 | 2 | 8 | 4 |
8. | Vlad Paiu (@vladpaiu) | 4 | 2 | 7 | 12 |
9. | Henning Westerholt (@henningw) | 4 | 2 | 6 | 31 |
10. | Andrei Pelinescu-Onciul | 4 | 2 | 4 | 4 |
All remaining contributors: Maksym Sobolyev (@sobomax), Eric Tamme (@etamme), Marcus Hunger, Sergio Gutierrez, Alexey Vasilyev (@vasilevalex), Jan Janak (@janakj), Konstantin Bokarius, Julián Moreno Patiño, Klaus Darilion, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Adrian Georgescu, Elena-Ramona Modroiu, Sergio Gutierrez.
(1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits)
(2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames".
(3) ignoring whitespace edits, renamed files and auto-generated files
Table 2.2. Most recently active contributors(1) to this module
Name | Commit Activity | |
---|---|---|
1. | Liviu Chircu (@liviuchircu) | Mar 2014 - May 2024 |
2. | Maksym Sobolyev (@sobomax) | Feb 2023 - Feb 2023 |
3. | Alexey Vasilyev (@vasilevalex) | Mar 2022 - Mar 2022 |
4. | Razvan Crainea (@razvancrainea) | Jun 2011 - Sep 2019 |
5. | Dan Pascu (@danpascu) | Mar 2004 - Aug 2019 |
6. | Bogdan-Andrei Iancu (@bogdan-iancu) | Jul 2005 - Apr 2019 |
7. | Vlad Patrascu (@rvlad-patrascu) | May 2017 - Apr 2019 |
8. | Peter Lemenkov (@lemenkov) | Jun 2018 - Jun 2018 |
9. | Julián Moreno Patiño | Feb 2016 - Feb 2016 |
10. | Eric Tamme (@etamme) | Jul 2014 - Jul 2014 |
All remaining contributors: Saúl Ibarra Corretgé (@saghul), Vlad Paiu (@vladpaiu), Sergio Gutierrez, Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Marcus Hunger, Klaus Darilion, Elena-Ramona Modroiu, Andrei Pelinescu-Onciul, Jan Janak (@janakj), Adrian Georgescu.
(1) including any documentation-related commits, excluding merge commits
Last edited by: Alexey Vasilyev (@vasilevalex), Liviu Chircu (@liviuchircu), Dan Pascu (@danpascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Saúl Ibarra Corretgé (@saghul), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu.
Documentation Copyrights:
Copyright © 2004 Dan Pascu