forked from fredrikt/yxa
-
Notifications
You must be signed in to change notification settings - Fork 2
/
README
389 lines (292 loc) · 14.3 KB
/
README
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
This is the YXA README file. YXA is a set of SIP servers written in Erlang.
This has been built using Erlang R15B and the bundled rebar script.
^^^^^^^^^^^^^^^^^
========
Building
========
In the top directory, use rebar to compile:
./rebar compile
=========
Releasing
=========
Use rebar to generate an embedded OTP release:
./rebar generate
This will create a new directory in the top level named 'sipserver'.
=====================
Installation, running
=====================
The release can be run in-place. No particular installation is prescribed.
To run:
./sipserver/bin/sipserver start
=======
Testing
=======
An escript can be made to test the currently-supported functions.
cd apps/siptest
../../rebar escriptize
This generates the siptest escript.
To run the tests:
./siptest invite 192.168.2.2
or
./siptest invite localhost
siptest assumes it is running on the same host as the server.
This will send an INVITE message to the server and wait until a response is
received. Instead of 'invite', 'options' can be used to send an OPTIONS request.
The response from the server is printed to stdout and the script exits.
============
Applications
============
simpleapp:
----------
This is provided for testing very minimal functionality of this simplified
version of yxa.
It will respond "486 Busy Here" to INVITE requests.
It will respond "AWESOME_STUFF" to OPTIONS requests.
eventserver:
------------
NOTE: this has not been built since the upgrade to rebar/R15B.
A release configuration should be added in rel/ to make an eventserver
release.
Framework for SIP event packages. Dialog stateful UAS.
Comes with default package handlers for the following packages :
presence RFC3856
dialog RFC4235
NOTE: The eventserver itself is probably working, but the event packages
are still under development and EXPERIMENTAL. Read more about the packages
below, under the topic "SIP Events".
=============
Configuration
=============
The configuration file is named <application>.config and can contain
these variables:
common:
-------
logger_logbasename (default: application name) Create log files
based on this. If you specify
/var/log/incomingproxy as logger_logbasename for
your incomingproxy, it will log to the files
/var/log/incomingproxy.debug (everything)
/var/log/incomingproxy.log (informational)
/var/log/incomingproxy.error (errors)
logger_logdir (default: current working directory) If
logger_logbasename is NOT set, a default logfile
basename will be created using this parameters
value, and the running applications name.
sipauth_realm (default: "") HTTP Auth realm
sipauth_password (default: "") HTTP Auth internal cookie
sipauth_unauth_classlist (default: []) Classes that anyone can call
sipauth_challenge_expiration (default: 30) How many seconds a challenge is
valid. Set to 0 to disable check for stale
authentication.
databaseservers (required if using remote databases)
Erlang node specification of the database
servers
listenport (default: 5060) Port that the server
should listen to
myhostnames (required) List of IP addresses and/or
hostnames of the host you run your server on.
The first entry in the list will be used
to symbolize this host in SIP packets
(Via headers and Record-Route headers (unless you
set record_route_url)).
Because of this, the first entry should really be
a real hostname for this host, and not a NAPTR/SRV
service name even if those NAPTR/SRV record points
at the real host. It doesn't hurt if there is also
NAPTR/SRV records for the real hostname though.
myips (no default) For some platforms autodetection of
the IP addresses of the network interfaces doesn't
work. If you have that problem, list your IP
addresses in this configuration parameter.
record_route (default: false, except for pstnproxy and outgoing-
proxy where default is true) Enable or disable
adding of Record-Route header to requests.
record_route_url (optional) A SIP (or SIPS) URI to use as Record-
Route, if we are configured to add Record-Route
headers. This makes it possible to for example
specifying the name of a cluster of machines in
the Record-Route headers, or to include port
number or other parameters if you find that you
have clients that require it.
Specifying a port number and a maddr=my-ip-address
is a way to get as much backwards compatibility as
possible, but also makes sure noone will try to
use anything besides UDP when following the Route.
default_max_forwards (default: 70) The Max-Forwards value we put in
requests that does not have one. Only change for
debugging, RFC3261 says this should be 70.
max_max_forwards (default: 255) Upper limit for Max-Forwards in
requests we send out. If we receive a request with
a Max-Forwards greater than this, we will use this
value instead of the received minus one.
detect_loops (default: true) Detect looping requests. Leave
this on.
request_rport (default: false) Request rport in outgoing
requests. Useful if you are sending through
a NAT device.
stateless_challenges (default: false) Send challenges without state
if this is true. RFC3261 suggests you should do
this, but there are problems with doing it...
See comments in transactionlayer.erl,
function send_challenge2().
stateless_send_ack_with_backup_plan: (default: true) Bend the stateless proxying
of request rules in RFC3261 slightly, to not
fail to proxy ACK of 2xx response because the
first destination resolved is not available.
Caveat: This works only for TCP/TLS destinations,
we currently can't detect that UDP destinations
are not available (we do check for blacklisted
destinations though).
tcp_connection_idle_timeout (default: 300) Number of seconds of inactivity
before we close a TCP connection.
tcp_connect_timeout (default: 20) Number of seconds before we time
out trying to establish a TCP connection to a
remote host.
udp_max_datagram_size (default: 1200) Max size of messages before we
switch from UDP to TCP. If you have phones that
only do UDP (and therefor suck), set this to
for example 3000.
userdb_modules (default: [sipuserdb_mnesia]) User database
backend(s) to use. See "User database" section
below.
enable_v6 (default: false) Enables IPv6 support. Read the
IPv6 paragraph below before enabling this!
max_logfile_size (default: 262144000 (250 MB)) Max filesize (in
bytes) before the logfiles are rotated. This
option will probably go away when we invent a
controlling mechanism so that things like
logfile size can be checked outside of YXA
instead, but this is needed for now since Erlang
crashes when the logfiles reach 2 GB. We only
check if the file size exceeds this limit every
60 seconds, not after every write. Set to 0 to
disable rotation (at your own risk).
timerT1 (default: 500) See RFC 3261. You should
probably not touch this.
timerT2 (default: 4000) See RFC 3261. You should
probably not touch this.
timerT4 (default: 5000) See RFC 3261. You should
probably not touch this.
sipsocket_blacklisting (default: true) Should we do blacklisting of
unreachable/unresponsive destinations so that we
avoid them for some time?
sipsocket_blacklist_duration (default: 120) The amount of time (measured in
seconds) that we should blacklist an unresponsive
destination.
sipsocket_blacklist_max (default: 3600) An upper limit of how long we
allow entrys to reside in our blacklist. This is
needed because the time could come from a
Retry-After header in a 503 response.
sipsocket_blacklist_probe_delay (default: 60) After how long time of blacklisting
should we start a background probe to see if the
destination has became reachable again? Set this
to something greater than
sipsocket_blacklist_duration if you want black-
listing but not probes. You should probably keep
this value at less than
sipsocket_blacklist_duration minus 32 seconds
(64*T1) to allow probes to time out before the
blacklisting expires, if the destination is still
unavailable/unresponsive.
stun_demuxing_on_sip_ports (default: false (except for outgoingproxy))
Should we demux and process STUN requests received
on our SIP ports? This is becoming a popular way
for clients to keep NAT bindings alive. See
draft-ietf-sip-outbound-03 for more information.
include_server_info_in_responses (default: true) Add a Server: header to
responses we create, to ease debugging/SIP call
tracing through a number of proxies.
event_handler_handlers (no default): event_handler gen_event handlers
to initialize. Should be a list of modules
(atoms) or a list of {Module, Args} of the
event handler takes arguments.
eventserver:
------------
eventserver_package_handlers (default: [{"presence", presence_package}])
presence_min_publish_time (default: 5)
presence_max_publish_time (default: 3600)
presence_default_publish_time (default: 600)
At the moment, configuration files must be in Erlang syntax. This involves lots
of brackets and curly brackets, and might be seen as an disadvantage for YXA.
Please bear with this though, as steps have been taken to make it easy to add
other configuration parsing backends. An ini-file format is likely to be written
shortly, and it would be fairly easy to write for example an XML-format parser
although you can't count on me doing it for you.
It is possible to include other files from within the top-level configuration
file (ie. you can't include a file from an included file). You do this by
specifying {include, "filename.conf"} as a parameter where you want the contents
of "filename.conf" to be included. The contents of filename.conf should not
contain any sections - see the example below. "filename.conf" will be considered
relative to the filename of the top-level configuration file, unless it is
absolute.
Brief introduction to the Erlang syntax :
{} - Curly brackets define a tuple. A tuple is like a list of fixed length, for
example {Key, Value} or {Key, Value1, Value2}.
[] - Brackets enclose lists. If a parameter can have any number of values
(like 'myhostnames' for example), the values will be in a list. Example :
{homedomain, ["example.com", "example.net", "example.org"]}
or, if you have just one domain
{homedomain, ["example.com"]}.
==================================
Application configuration examples
==================================
simpleapp:
----------
[{myhostnames, ["192.168.2.2"]}]
============
IPv6 support
============
If you enable IPv6 support, you need to add your v6 addresses to the
myhostnames configuration variable, because siphost:myip_list() is currently
not capable of detecting your IPv6 address (Erlang OTP R9C-0). If you don't
do this, then lookup:homedomain() will not work properly and you might get
problems with requests sent with a URI containing your IPv6 address.
IPv6 support is disabled by default, because you need to know what you are
doing before turning it on. If you enable it to make proxy-to-proxy
communication use v6 and a v6-only proxy adds Record-Route headers, then
v4-only clients won't be able to reach the v6-only proxy. This could be
fixed by making YXA always Record-Route when receiving a request over v4/v6
and sending it out using the other but then there is still the problem with
v6-only phones responding to INVITE with a SDP offer containing a v6 address.
How will a v4-only phone be able to send audio to that phone, and receive
audio from that phone? v6 is disabled by default.
If you are using Linux, then you will need to
# echo 1 > /proc/sys/net/ipv6/bindv6only
since YXA wants to use separate sockets for v6 and v4. IPv6 support has only
been tested on Linux 2.4.x where x >= 20, and Linux 2.6.x where x >= 14.
Note on Erlang OTP R10B-0 through R10B-6 :
The resolver order was changed in R10B, so now Erlang primarily tries to use
the 'native' resolver (meaning a C port driver) for DNS resolution.
Unfortunately, this C port driver only handles getipnodebyname() and not
getaddrinfo(). The latter is a POSIX standard, and the one that should be used.
This means that you might not get IPv6 addresses back from
dnsutil:get_ip_port(), which in turn means YXA won't make outgoing connections
to IPv6 addresses. This is a problem with some versions of Linux (for example,
RH7.3 to RH9 based systems).
====================
SIP Events (RFC3265)
====================
The YXA application 'eventserver' handles subscriptions for SIP events in a
modular fashion. The goal is to separate subscription handling, with all the
issues regarding expiration and renewing of subscriptions, from the event
packages. Event packages are Erlang modules implementing the behaviour
'event_package'. There following event packages exist, and are enabled per
default :
presence : This is a presence state agent (presence server), that stores
presence that clients send using PUBLISH in a Mnesia database.
It is possible to have a distributed presence server with more
than one eventserver, running on more than one Erlang node.
Currently, all users in your domain are allowed to subscribe
to all other users in your domains presence. Users outside
your domain is not allowed to subscribe to your users presence
at all. The presence status of your users can also be obtained
through a bidirectional subscription (the eventserver subscri-
bes to your user when it subscribes to someone else), but this
is done on a per-User-Agent basis and probably requires you to
patch the code slightly. Anyone interested in implementing
XCAP for access control lists etc. should let me know, that
would be great. I won't do it.
dialog : A dialog state agent. The goal was to get 'shared line'
working on my Snom phones. Can't say I'm there just yet.
NOTE that ALL these event packages are currently to be considered
experimental.