-
Notifications
You must be signed in to change notification settings - Fork 52
/
README
1113 lines (873 loc) · 43 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
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
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
This is the YXA README file. YXA is a set of SIP servers written in Erlang.
To install YXA, you need to have Erlang/OTP R13B-1 installed (up to R1501 allowed).
Quick installation guide :
$ tar zxvf yxa-version.tar.gz
$ mkdir build
$ cd build
$ ../yxa-version/configure && make && make install
and then start configuring your new SIP server(s). These steps are
described in more detail below, so keep on reading.
If you run into problems, check the archive of the yxa-devel mailing list
and if the answer to your question is not to be found in the archives then
subscribe to the list (necessary for posting) and ask.
YXA-devel : https://lists.su.se/mailman/listinfo/yxa-devel
YXA-announce : https://lists.su.se/mailman/listinfo/yxa-announce
(the announce-list is moderated and only gets e-mail when there is a new
snapshot or release available).
============
Applications
============
Applications included are:
incomingproxy:
Handles registrations and proxies requests. Implements partial ENUM
and LDAP searches. Handles most everything you need to set up SIP for your
domain.
outgoingproxy:
Special proxy for clients behind NAT. Makes it possible for clients to
receive all requests to them through a persistent TCP connection the client
has set up with the outgoingproxy. You still need an incomingproxy, and you
need to point your outgoingproxy at it through the 'sipproxy' configuration
parameter.
pstnproxy:
Designed as an authentication frontend to an insecure PSTN gateway.
Supports the expired-draft-only header Remote-Party-Id to signal
what PSTN phone number to use when sending requests to the PSTN
gateway, and, if an LDAP server is configured, looks for a Display
Name to use for calls from the PSTN gateway. Can route calls from
the PSTN either via ENUM or to a preconfigured SIP gateway.
appserver:
Provides basic forking and CPL script interpretation. If a user has
multiple active contacts, or a CPL script associated with it, incomingproxy
will send requests for that user on to appserver which is a statefull proxy
and can fork the call to all the users registered user agents or according
to the users CPL script.
eventserver:
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".
testserver:
Not useful for anything except regression testing. Answers 404 Not Found
(or some other failure response) to everything, so that one can do
regression tests of the incomingproxy for example by making sure it
routes requests correctly to the testserver.
============
Installation
============
1) Unpack the source
2) Change working directory to where you unpacked the source
3) Optionally, but preferrably - create a sub-directory called 'build'
or whatever you desire (this does not have to be a sub-directory to
where you unpacked the source).
4) Change into the 'build' directory you created in step 3.
5) Run ../configure && make && sudo make install
If you are building source retreived from CVS, you will have to generate
the "configure" script by running "autoconf" in the source directory first.
The autoconf version known to work with the current sources is 2.59.
6) Bootstrap your new installation. See "Bootstrapping" below.
7) Configure the YXA applications you want to use (see "Configuration" below).
8) Start the YXA applications you configured in step 7. To start an
incomingproxy application, execute the incomingproxy script with the
single argument 'start' :
$ incomingproxy start
Then check the log files for incomingproxy to see if it says
'proxy started'. If you haven't set logger_logbase or logger_logdir, the
three log files incomingproxy.debug, .log and .error will end up in your
current directory where you started incomingproxy from. If you run into
problems, and don't see anything in the logfiles (not even in the .debug
log file), start incomingproxy (or whichever application it is you are
having problems with) in the debug mode by using -d. -d implies 'start' :
$ incomingproxy -d
You will now end up in an Erlang shell 'console', or see more error
information hopefully telling you why your YXA application does not start.
To exit the console, hit Ctrl+C twice, or execute the Erlang command
"halt()." (without the quotes).
Configure options special to YXA :
--disable-erlang-version-check
Ignore result of the Erlang/OTP version check.
--with-erlang The path to your Erlang/OTP installation's
'bin' directory.
--with-mnesiadir The path to where you want your Mnesia
database files. Default is "/var/yxa/db".
--with-sslcertdir The path to where you keep your SSL certificate
files (cert.comb).
--with-local The Erlang module to use for local customizations.
This is a file containing hooks for all sorts of
things, making it possible to make your own
extensions to YXA. The default is
'local_default.erl', but 'local_su.erl' and
'local_kth.erl' are also included in the
distribution. Copy 'local_default.erl' to
'local_your_domain.erl' and use
--with-local='local_your_domain' if you want
to make your own custom local.erl.
===
SSL
===
If you want to use SSL (normally enabled), either put your combined
private and public X.509 key in ssl/cert.comb or edit the ssl.config
in the source directory and do "make sslkey" to get a self-signed
certificate. The certificate password must be "foobar" if you use
"make sslkey". This SSL is only for use by the Erlang distributed operation
system (see below), it has nothing to do with SIP TLS.
If you get an error like "problems making Certificate Request" and
... "string too long" ... then you did not change the "req_distinguished_name"
in ssl.config to your hostname.
=====================
Distributed operation
=====================
If you want to setup a distributed erlang system, you must have the
same ~/.erlang.cookie file on all nodes. Also, if you have SSL (see SSL topic
above) enabled on one node, you must have it enabled on all the other nodes
as well. Distributed operation includes having the same Mnesia-tables readable
on more than the local node, so you most probably should do this if you run
more than one YXA node.
=============
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
ldap_server (default: "" (ie. no LDAP)) LDAP server host name
ldap_username (default: "") LDAP user name
ldap_password (default: "") LDAP password
ldap_searchbase (default: "") LDAP search base
ldap_use_ssl (default: false) Connect to LDAP server using SSL
if true.
ldap_connection_query_limit (default: 500) When we have made this many querys
using an LDAP handle, open a new one (as soon as
we are idle).
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).
ssl_require_client_has_cert (default: false) Reject connections from TLS
clients that don't use a client certificate.
ssl_server_certfile (no default) Filename of your SSL (TLS) server
certificate. SIP proxys are required to support
TLS.
ssl_server_ssloptions (default: []) SSL server SSL options, see
ssl(3erl) (the Erlang SSL documentation) for more
information, but you should for example be able
to for example use a separate file for your
certificates key by setting this to
[{keyfile, "/path/to/cert.key"}].
ssl_client_ssloptions (default: []) SSL client SSL options, see
ssl(3erl) (the Erlang SSL documentation) for more
information, but you should for example be able
to get the SSL client to verify the certificates
of servers it connects to by setting this to
[{cacertfile, "/path/to/root-cert.pem"},
{verify, 2}, {depth, 2}].
ssl_check_subject_altname (default: true) Whether we should reject SSL
server certificates with subjectAltName/CN not
matching whatever hostname/domainname we expected.
ssl_check_subject_altname_allow_servername (default: true) Treat NAPTR/SRV host-
name as valid subjectAltName/CN in certificates.
ssl_require_sips_registration (default: true) If you leave this at 'true', your
users phones must register with SIPS URIs to be
contacted for a request with a SIPS Request-URI.
If you set it to 'false' then the communication
between your registrar and your phones are
considered safe even if it is not protected by
TLS.
tls_listenport (default: 5061) The port we should listen for TLS
connections on.
tls_disable_client (default: false) Set this to 'true' to make this
proxy not connect to other proxys using TLS.
tls_disable_server (default: false) Set this to 'true' to not listen
for TLS connections at all. Proxys are required
to support SIP over TLS, so setting this to
'true' is NOT recommended.
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.
pstnproxy:
----------
e164_to_pstn (no default) Regexps for choosing PSTN gateway
to use for E.164 numbers.
number_to_pstn (no default) The same as e164_to_pstn, but
consulted if a number could not be rewritten
to an E.164 number (like an internal-only
number).
pstngatewaynames (required) List of IP addresses and/or
hostnames of your PSTN gateway.
Incoming requests will be matched against
this list when checking if they are from the
PSTN gateway or not.
default_pstngateway (no default) Name of gateway to which we should
route requests to PSTN if a lookup of the number
in e164_to_pstn does not result in an address.
classdefs (default: [{"", unknown}]) Regexps for
classifying phone numbers. Used to determine if
a call from a user (or unknown party) should be
permitted or not.
sipproxy (default: "") The name of the SIP proxy to route
calls from the PSTN gateway to. This is something
like a default SIP route. If you enable ENUM in
the pstnproxy, ENUM is considered before
sipproxy. If you do not enter a sipproxy, and
the number being called is not found using ENUM,
503 Service Unavailable will be returned.
enum_domainlist (no default) List of domains in which to look
for NAPTR-records for requests _from_ the
PSTN gateway. If you use this, you probably
also want to configure internal_to_e164. The
global E.164 root is e164.arpa, so an example
would be ["e164.arpa", "e164.example.com"].
All domains will be queried and after that
the answers will be sorted and the best one
will be used.
internal_to_e164 (default: []) Regexps for rewriting
internal numbers to E.164 numbers. In pstnproxy,
this is only used to query ENUM - NOT for
rewriting stuff to E.164 before passing them
to the PSTN gateway.
remote_party_id (default: false) If you set this to true, then
the pstnproxy will try to add information
about the caller in a header called
Remote-Party-Id. This is not a standard, but
current versions of Cisco IOS (12.2.15T)
supports it so it is nice to have. If you
also configure LDAP for the pstnproxy, this
function will try to look up a name to use
in calls from the PSTN gateway, but I haven't
seen a phone that displays this yet.
pstnproxy_no_sip_dst_code (default: 480) SIP error code to return for
requests from PSTN to SIP when the destination is
not found in ENUM, and no sipproxy has been
configured. This is configurable since you might
want your gateway to act in a special way in this
situation, for example falling back to using PSTN
or something.
pstnproxy_redirect_on_enum (default: false) If you set this to true, we will
send a redirect (302) back to the caller when we
find a destination for the request in ENUM,
instead of proxying to the destination (only
applys to calls from PSTN to SIP).
x_yxa_peer_auth_secret (no default, not required) Shared secret for this
pstnproxy to use for allowing requests forwarded
to PSTN on behalf of a particular user using
appserver.
allowed_request_methods (default: ["INVITE", "ACK", "PRACK", "CANCEL",
"BYE", "OPTIONS"]) What SIP requests
we should allow to reach our PSTN gateways.
pstnproxy_challenge_bye_to_pstn_dst (default: true) Should we challenge BYEs sent
towards a PSTN gateway? NOTE: This does NOT work
if you have 'free' classes, since we are not
dialog stateful and therefor can't know that the
BYE is sent to a 'free' destination.
pstnproxy_allow_reinvite_to_pstn_dst (default: true) Should re-INVITEs on
existing dialogs be allowed?
incomingproxy:
--------------
internal_to_e164 (default: []) Regexps for rewriting
internal numbers to E.164 numbers.
e164_to_pstn (default: []) Regexps for choosing PSTN gateway/
pstnproxy to use for E.164 numbers.
number_to_pstn (default: []) The same as e164_to_pstn, but
consulted if a number could not be rewritten to
a E.164 number (like an internal-only number).
defaultroute (default: "") SIP host name part of default
route. Note that if you use e164_to_pstn, you
don't have to point defaultroute at your
PSTN gateway.
homedomain (required) List of SIP domains this proxy
should handle requests for.
enum_domainlist (no default) List of domains in which to look
for NAPTR-records for requests that are not
to SIP-users but where the user part matches
one of the regexps in internal_to_e164. The
global E.164 root is e164.arpa, so an example
would be ["e164.arpa", "e164.example.com"].
All domains will be queried and after that
the answers will be sorted and the best one
will be used.
max_register_time (default: 43200) If registers have an 'expire'
of more than this many seconds, use this
value instead.
always_verify_homedomain_user (default: true) If From: matches our definition
of 'our' domains (matched by homedomain), then
challenge user and make sure it is not someone
impersonating the calling party.
authenticate_in_dialog_requests (default: false) Should we perform the From:
check above for all in-dialog requests, or only
the first one that establishes the request?
Default is to only verify the first one.
appserver (default: "") URL to where to send requests
when there are more than a single location
for a request found in the location database,
or when the request is destined for a user who
has a CPL script.
Example: "appserver.example.com" or
"sip:sipserver.example.com:5090".
eventserver (default: "") URL to where to send SUBSCRIBE
and PUBLISH requests. Point this at your
eventserver (another YXA application) or some
other server that handles RFC3265 SIP events
in your domain.
Example: "eventserver.example.com" or
"sip:sipserver.example.com:5040".
eventserver_for_package (default: []) More fine grained control over
which server should handle a specific type of
events in your domain. Checked before the
'eventserver' configuration parameter.
Example:
[{"presence", "sip:presence.example.com"},
{"ua-config", "sip:prov.example.com"}
]
outgoingproxy:
--------------
sipproxy (required) The location of your incomingproxy.
Example: "incomingproxy.example.com" or
"sip:incomingproxy.example.com:5090".
max_register_time (default: 43200) If registers have an 'expire'
of more than this many seconds, use this
value instead.
homedomain (required) List of SIP domains this proxy
should handle requests for.
allow_foreign_registers (default: false) Set to true to have your out-
goingproxy forward non-local REGISTERs to other
proxys. Defaults to false since it doesn't make
much sense for the clients to use the outgoing-
proxy in the first place if they register with
a domain that the outgoingproxy doesn't consider
local (what domains are 'local' is determined
by the 'homedomain' parameter).
stun_demuxing_on_sip_ports (default: true) Allow clients to keep NAT
bindings alive by (quite frequently) send STUN
requests to the outgoingproxy on the same socket
used for SIP signalling. See
draft-ietf-sip-outbound-03 for more information.
appserver:
----------
internal_to_e164 (default: []) Regexps for rewriting
internal numbers to E.164 numbers. The
appserver must have identical
internal_to_e164 with the incomingproxy
to be able to make the exact same routing
decisions.
appserver_call_timeout (default: 40) The number of seconds to ring
a destination before concluding that noone
answers.
appserver_forward_timeout (default: 40) The same as appserver_call_timeout
but for forwarded calls.
x_yxa_peer_auth (default: []) List of {host, secret} shared
secrets to use when sending out requests on
behalf of a user with forwards or a CPL script.
Example : [{"pstnproxy.example.com", "secret"}]}.
See also x_yxa_peer_auth_secret to make pstnproxy
at pstnproxy.example.com accept the requests.
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
==================================
incomingproxy.config:
---------------------
[{incomingproxy, [{sipauth_realm, "example.com"},
{sipauth_password, "secret"},
{defaultroute, "other-sipserver.example.com"},
{logger_logbasename, "/var/log/incomingproxy"},
{internal_to_e164, [{"^00(.+)$", "+\\1"},
{"^0(.+)$", "+46\\1"},
{"^(.+)$", "+468\\1"}
]},
{e164_to_pstn, [{"^\\+468([1-9][0-9]+)$", "00\\[email protected]"},
{"^\\+46([1-9][0-9]+)$", "000\\[email protected]"},
{"^\\+44([1-9][0-9]+)$", "000\\[email protected]"},
{"^\\+([0-9]+)$", "0000\\[email protected]"}
]},
{number_to_pstn, [{"^118$", "[email protected]"}]},
{enum_domainlist, ["e164.arpa"]},
{homedomain, ["example.com", "example.net", "example.org"]},
{myhostnames, ["sipserver.example.com", "sip.example.net", "sip.example.org"]},
{appserver, "appserver.example.com:5070"},
{eventserver, "eventserver.example.com"},
{ldap_server, "ldap.example.com"}
]}].
outgoingproxy.config:
---------------------
[{outgoingproxy, [{sipauth_realm, "example.com"},
{sipauth_password, "secret"},
{databaseservers, ['[email protected]']},
{myhostnames, ["outgoingproxy1.example.com", "out.example.com"]},
{homedomain, ["example.com", "example.net", "example.org"]},
{tcp_connection_idle_timeout, 1000000}
]}].
pstnproxy.config:
-----------------
[{pstnproxy, [{sipauth_realm, "example.com"},
{sipauth_password, "secret"},
{sipauth_unauth_classlist, [internal]},
{logger_logbasename, "/var/log/pstnproxy"},
{pstngatewaynames, ["pstn-gw.example.com", "10.10.1.1"]},
{myhostnames, ["sip-pstn.example.com", "sip2pstn.example.com", "10.10.1.2"]},
{classdefs, [{"^[1-9]", national},
{"^0[1-9]", national},
{"^00", international},
{"", unknown}
]},
{databaseservers, ['[email protected]']},
{internal_to_e164, [{"^00(.+)$", "+\\1"},
{"^0(.+)$", "+46\\1"},
{"^(.+)$", "+468\\1"}
]},
{e164_to_pstn, [{"^\\(+44[1-9][0-9]+)$", "\\[email protected]"}]},
{number_to_pstn, [{"^118$"}, "sip:[email protected]"]},
{enum_domainlist, ["e164.arpa"]},
]}].
appserver.config:
-----------------
[{appserver, [{sipauth_realm, "example.com"},
{sipauth_password, "secret"},
{logger_logbasename, "/var/log/appserver"},
{internal_to_e164, [{"^00(.+)$", "+\\1"},
{"^0(.+)$", "+46\\1"},
{"^(.+)$", "+468\\1"}
]},
{databaseservers, ['[email protected]']},
{myhostnames, ["appserver.example.com", "10.10.1.1"]},
{record_route, true},
{listenport, 5070}
]}].
Combined configuration file for more than one application :
-----------------------------------------------------------
yxa.config :
[
%% Include files
%% --------------------------------------------------------------------
{include, "secrets.config"},
%% Common configuration
%% --------------------------------------------------------------------
{common, [{sipauth_realm, "example.com"},
{logger_logdir, "/var/log/yxa"},
{databaseservers, ['[email protected]']},
{ssl_server_certfile, "/var/yxa/ssl/cert.comb"},
{ssl_client_certfile, "/var/yxa/ssl/cert.comb"},
{ssl_server_ssloptions, [{verify, 1},
{cacertfile, "/var/yxa/ssl/ca-chain.crt"}
]},
{ssl_client_ssloptions, [{verify, 1},
{cacertfile, "/var/yxa/ssl/ca-chain.crt"}
]}
]},
%% Application specific configuration
%% --------------------------------------------------------------------
{incomingproxy, [{appserver, "appserver.server.example.com"},
{myhostnames, ["incomingproxy.server.example.com", "server.example.com"]},
{homedomain, ["example.com", "example.net", "example.org"],
{enum_domainlist, ["e164.arpa"]}
]},
{appserver, [{listenport, 5070},
{tls_listenport, 5071}
]}
].
secrets.config :
[
{common, [{sipauth_password, "secret"}
]}
].
======================================
User database (sipuserdb_file) example
======================================
[
{user, [
{name, "ft.sip1"},
{password, "secret"},
{classes, [internal,national,mobile]}
]},
{user, [
{name, "[email protected]"},
{password, "secret2"},
{classes, [internal]},
{addresses, ["sip:[email protected]", "sip:[email protected]"]}
]},
{address, [
{user, "ft.sip1"},
{address, "sip:[email protected]"}
]},
{address, [
{user, "ft.sip1"},
{address, "sip:[email protected]"}
]}
].
This is a simple user database. If I have two phones, and let one REGISTER
with 'To: sip:[email protected]' and authentication username 'ft.sip1', and
the other REGISTER with 'To: sip:[email protected]' and authentication
username '[email protected]' (NOTE: no "sip:"), calls to sip:[email protected]
will cause phone #1 to ring and calls to sip:[email protected] will cause
phone #2 to ring. Calls to sip:[email protected] will cause both phones to
ring, provided that I have an incomingproxy and an appserver set up and
configured. Note that addresses can either be supplied as part of the
'user' declaration (user '[email protected]'), or separately (user 'ft.sip1').
=============
User database
=============
YXA has a modular interface for user database backends. The entry point is
the sipuserdb module, which looks at your configuration to determine which
database backends to query, and in what order. The default is to just look
in the Mnesia database (tables user and numbers), but there is also an
LDAP module, MySQL module and a plain text file backend available. The
schema for storing SIP user information in LDAP is not yet finished, and
is currently not even included in the YXA source, but the sipuserdb_ldap
module is used in production at Stockholm university.
sipuserdb_ldap configuration parameters :
-----------------------------------------
ldap_userattribute (deafult: sipAuthenticationUser) User
attribute.
ldap_addressattribute (default: sipLocalAddress) User SIP address
attribute.
ldap_telephonenumberattribute (default: telephoneNumber) User phone number
attribute.
ldap_passwordattribute (default: sipPassword) User authentication
password attribute.
sipuserdb_file configuration parameters :
-----------------------------------------
sipuserdb_file_filename (required) Filename (including path) of
your user database. See above (section
Examples) for format of this file.
sipuserdb_file_refresh_interval (default: 15) Interval (in seconds) between
checks for updated user database file.
sipuserdb_mysql configuration parameters :
------------------------------------------
sipuserdb_mysql_host (required) Server name. Example :
"mysql-srv.example.org"
sipuserdb_mysql_port (default: 3306) Server port. Example :
33060
sipuserdb_mysql_user (required) MySQL username to log in with.
Example : "yxa"
sipuserdb_mysql_password (required) MySQL password to log in with.
Example : "secret"
sipuserdb_mysql_database (required) MySQL database to use.
Example : "yxadb"
MySQL query configuration parameters :
--------------------------------------
The default YXA MySQL userdb querys are simple. They can be somewhat
'personalized' by changing the templates. All querys are made for a single
key (or list of keys, when for example looking for all users matching a
number of addresses), and the query is constructed by inserting the quoted
key value everywhere in the templates where there is a '?'.
If you want to construct more advanced querys than can be done using these
templates, look at creating a custom sipuserdb_mysql_make_sql_statement/2
function in your local.erl.
If you have to do special processing of some return values (for example
decrypting passwords after reading them from the database), override the
get-function you are interested in altering using for example the
sipuserdb_backend_override/3 function in your local.erl.
sipuserdb_mysql_get_user
(default: "select sipuser from users where sipuser = ?")
Query to use when trying to validate a users existence. Can also
be used to map multiple usernames to a single 'primary' username,
which will be the key used when looking for a users location(s)
in the location database for example.
sipuserdb_mysql_get_user_for_address
(default: "select sipuser from addresses where address = ?")
sipuserdb_mysql_get_addresses_for_user
(default: "select address from addresses where sipuser = ?")
sipuserdb_mysql_get_classes_for_user
(default: "select class from classes where sipuser = ?")
sipuserdb_mysql_get_password_for_user
(default: "select password from users where sipuser = ?")
sipuserdb_mysql_get_telephonenumber_for_user
(default: "select address from addresses where sipuser = ? and
is_telnr = 'Y'")
Table definitions matching the default querys :
CREATE TABLE users (
sipuser VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL
);
CREATE TABLE addresses (
address VARCHAR(255) NOT NULL,
sipuser VARCHAR(255) NOT NULL,
is_telnr ENUM('Y', 'N') DEFAULT 'N'
);
CREATE TABLE classes (
sipuser VARCHAR(255) NOT NULL,
class VARCHAR(255) NOT NULL
);
=============
Bootstrapping
=============
In your build directory, or in the directory you chosed to have the executable
files installed in (default: /usr/local/XXX) you should have a file called
yxa-bootstrap. Execute this script, and it will create a Mnesia schema and all
the needed Mnesia tables for you. By default, the incomingproxy application will
be Mnesia database master. If you do not wish to have some other node be the
Mnesia database master, you should execute yxa-bootstrap on the server that
you will be running incomingproxy on.
Example :
$ /path/to/yxa-bootstrap
You should now have the necessary Mnesia database and tables.
All of the YXA application can run just fine without root permissions.
If you want to have more than one incomingproxy node (and thus more than
one database master node), do the following on incomingproxy server #1 :
$ /path/to/yxa-bootstrap
and then, on incomingproxy server #2 :
$ /path/to/yxa-bootstrap -replica [email protected]
You should then set the configuration parameter databaseservers like this
on all your non-incomingproxy nodes :
{databaseservers, ['[email protected]',
If you want some other YXA application node than incomingproxy to be your
Mnesia database master, supply the -name argument to yxa-bootstrap. For
example, if you are only using the pstnproxy, invoke yxa-bootstrap like
this :
$ /path/to/yxa-bootstrap -name pstnproxy
=============
Web interface
=============