1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469
|
<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
%docentities;
]>
<!-- Module User's Guide -->
<chapter>
<title>&adminguide;</title>
<section>
<title>Overview</title>
<para>
Mediaproxy is an &siprouter; 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.
</para>
</section>
<section>
<title>Principle of operation</title>
<para>
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.
</para>
<para>
Mediaproxy consists of 2 components:
<itemizedlist>
<listitem>
<para>The &siprouter; mediaproxy module</para>
</listitem>
<listitem>
<para>
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).
</para>
</listitem>
</itemizedlist>
</para>
<para>
The mediaproxy dispatcher runs on the same machine as &siprouter;
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.
</para>
<para>
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.
</para>
<para>
&siprouter; 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 &siprouter; the IP address and port(s) for them. Then &siprouter; 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.
</para>
<para>
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.
</para>
</section>
<section>
<title>Features</title>
<para>
<itemizedlist>
<listitem>
<para>
make symmetric clients work behind NAT transparently, with no
configuration needed on the client's NAT box.
</para>
</listitem>
<listitem>
<para>
have the ability to distribute RTP traffic on multiple media relays
running on multiple hosts.
</para>
</listitem>
</itemizedlist>
</para>
</section>
<section>
<title>Dependencies</title>
<section>
<title>&siprouter; Modules</title>
<para>
The following modules must be loaded before this module:
<itemizedlist>
<listitem>
<para>
<emphasis>dialog</emphasis> module - if engage_media_proxy is used
(see below the description of engage_media_proxy).
</para>
</listitem>
</itemizedlist>
</para>
</section>
<section>
<title>External Libraries or Applications</title>
<para>
The following libraries or applications must be installed before
running &siprouter; with this module loaded:
<itemizedlist>
<listitem>
<para>
<emphasis>Mediaproxy version 2.4.2 or higher (but not
necessarily on the same host as &siprouter;)</emphasis>.
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section>
<title>Exported parameters</title>
<section>
<title><varname>disable</varname> (int)</title>
<para>
Boolean flag that specifies if mediaproxy should be disabled. This
is useful when you want to use the same openser 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.
</para>
<para>
<emphasis>
Default value is <quote>0</quote>.
</emphasis>
</para>
<example>
<title>Setting the <varname>disable</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("mediaproxy", "disable", 1)
...
</programlisting>
</example>
</section>
<section>
<title><varname>mediaproxy_socket</varname> (string)</title>
<para>
It is the path to the filesystem socket where the mediaproxy dispatcher
listens for commands from the module.
</para>
<para>
<emphasis>
Default value is
<quote>/var/run/mediaproxy/dispatcher.sock</quote>.
</emphasis>
</para>
<example>
<title>Setting the <varname>mediaproxy_socket</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("mediaproxy", "mediaproxy_socket", "/var/run/mediaproxy/dispatcher.sock")
...
</programlisting>
</example>
</section>
<section>
<title><varname>mediaproxy_timeout</varname> (int)</title>
<para>
How much time (in milliseconds) to wait for an answer from the
mediaproxy dispatcher.
</para>
<para>
<emphasis>
Default value is <quote>500</quote>.
</emphasis>
</para>
<example>
<title>Setting the <varname>mediaproxy_timeout</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("mediaproxy", "mediaproxy_timeout", 500)
...
</programlisting>
</example>
</section>
<section>
<title><varname>signaling_ip_avp</varname> (string)</title>
<para>
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.
</para>
<para>
<emphasis>
Default value is <quote>$avp(signaling_ip)</quote>.
</emphasis>
</para>
<example>
<title>Setting the <varname>signaling_ip_avp</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("mediaproxy", "signaling_ip_avp", "$avp(nat_ip)")
...
</programlisting>
</example>
</section>
<section>
<title><varname>media_relay_avp</varname> (string)</title>
<para>
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.
</para>
<para>
<emphasis>
Default value is <quote>$avp(media_relay)</quote>.
</emphasis>
</para>
<example>
<title>Setting the <varname>media_relay_avp</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("mediaproxy", "media_relay_avp", "$avp(media_relay)")
...
</programlisting>
</example>
</section>
<section>
<title><varname>ice_candidate</varname> (string)</title>
<para>
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 adeed 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.
</para>
<para>
<emphasis>
Default value is <quote>none</quote>.
</emphasis>
</para>
<example>
<title>Setting the <varname>ice_candidate</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("mediaproxy", "ice_candidate", "low-priority")
...
</programlisting>
</example>
</section>
<section>
<title><varname>ice_candidate_avp</varname> (string)</title>
<para>
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. If the AVP
is not set, the default value will be used.
</para>
<para>
<emphasis>
Default value is <quote>$avp(ice_candidate)</quote>.
</emphasis>
</para>
<example>
<title>Setting the <varname>ice_candidate_avp</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("mediaproxy", "ice_candidate_avp", "$avp(ice_candidate)")
...
</programlisting>
</example>
</section>
</section>
<section>
<title>Functions</title>
<section>
<title><function moreinfo="none">engage_media_proxy()</function></title>
<para>
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.
</para>
<para>
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().
</para>
<para>
This function can be used from REQUEST_ROUTE.
</para>
<example>
<title>Using the <function>engage_media_proxy</function> function</title>
<programlisting format="linespecific">
...
if (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();
}
...
</programlisting>
</example>
</section>
<section>
<title><function moreinfo="none">use_media_proxy()</function></title>
<para>
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.
</para>
<para>
This function should NOT be mixed with engage_media_proxy().
</para>
<para>This function has the following return codes:</para>
<para>
<itemizedlist>
<listitem><para>
+1 - successfully modified message (true value)
</para></listitem>
<listitem><para>
-1 - error in processing message (false value)
</para></listitem>
<listitem><para>
-2 - missing SDP body, nothing to process (false value)
</para></listitem>
</itemizedlist>
</para>
<para>
This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
</para>
<example>
<title>Using the <function>use_media_proxy</function> function</title>
<programlisting format="linespecific">
...
if (method==INVITE) {
# We can also use a specific media relay if we need to
#$avp(media_relay) = "1.2.3.4";
use_media_proxy();
}
...
</programlisting>
</example>
</section>
<section>
<title><function moreinfo="none">end_media_session()</function></title>
<para>
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.
</para>
<para>
This function should NOT be mixed with engage_media_proxy().
</para>
<para>
This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
</para>
<example>
<title>Using the <function>end_media_session</function> function</title>
<programlisting format="linespecific">
...
if (method==BYE) {
end_media_session();
}
...
</programlisting>
</example>
</section>
</section>
</chapter>
|