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 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507
|
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<section id="operation" xmlns:xi="http://www.w3.org/2001/XInclude">
<sectioninfo>
<revhistory>
<revision>
<revnumber>$Revision$</revnumber>
<date>$Date$</date>
</revision>
</revhistory>
</sectioninfo>
<title>Server Operation</title>
<section id="operationalpractices">
<title>Recommended Operational Practices</title>
<para>
Operation of a SIP server is not always easy task.
Server administrators are challenged by broken or
misconfigured user agents, network and host failures,
hostile attacks and other stress-makers. All such
situations may lead to an operational failure. It is sometimes
very difficult to figure out the root reason of
a failure, particularly in a distributed environment
with many SIP components involved.
In this section,
we share some of our practices and refer to tools
which have proven to
make life of administrators easier
</para>
<qandaset>
<qandaentry>
<question>
<para>
Keeping track of messages is good
</para>
</question>
<answer>
<para>
Frequently, operational errors are discovered or reported
with a delay.
Users frustrated by an error
frequently approach administrators
and scream "even though my SIP requests were absolutely ok
yesterday, they were mistakenly denied by your server".
If administrators do not record all SIP traffic at
their site, they will be no more able to identify
the problem reason.
We thus recommend that site
operators record all messages passing their site and keep them
stored for some period of time.
They may use utilities such as
<application>ngrep
</application> or
<application>tcpdump
</application>.
There is also a utility <application>
scripts/harv_ser.sh</application> in <application>
ser</application> distribution for post-processing
of captured messages. It summarizes messages captured
by reply status and user-agent header field.
</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>
Real-time Traffic Watching
</para>
</question>
<answer>
<para>
Looking at SIP messages in real-time may help to gain
understanding of problems. Though there are commercial
tools available, using a simple, text-oriented tool
such as <application>ngrep</application> makes the job very well thanks to SIP's textual nature.
</para>
<example id="usingngrep">
<title>Using <application>ngrep</application>
</title>
<para>In this example, all messages at port 5060
which include the string "bkraegelin" are captured
and displayed</para>
<programlisting>
[jiri@fox s]$ ngrep bkraegelin@ port 5060
interface: eth0 (195.37.77.96/255.255.255.240)
filter: ip and ( port 5060 )
match: bkraegelin@
#
U +0.000000 153.96.14.162:50240 -> 195.37.77.101:5060
REGISTER sip:iptel.org SIP/2.0.
Via: SIP/2.0/UDP 153.96.14.162:5060.
From: sip:bkraegelin@iptel.org.
To: sip:bkraegelin@iptel.org.
Call-ID: 0009b7aa-1249b554-6407d246-72d2450a@153.96.14.162.
Date: Thu, 26 Sep 2002 22:03:55 GMT.
CSeq: 101 REGISTER.
Expires: 10.
Content-Length: 0.
.
#
U +0.000406 195.37.77.101:5060 -> 153.96.14.162:5060
SIP/2.0 401 Unauthorized.
Via: SIP/2.0/UDP 153.96.14.162:5060.
From: sip:bkraegelin@iptel.org.
To: sip:bkraegelin@iptel.org.
Call-ID: 0009b7aa-1249b554-6407d246-72d2450a@153.96.14.162.
CSeq: 101 REGISTER.
WWW-Authenticate: Digest realm="iptel.org", nonce="3d9385170000000043acbf6ba9c9741790e0c57adee73812", algorithm=MD5.
Server: Sip EXpress router(0.8.8 (i386/linux)).
Content-Length: 0.
Warning: 392 127.0.0.1:5060 "Noisy feedback tells: pid=31604 req_src_ip=153.96.14.162 in_uri=sip:iptel.org out_uri=sip:iptel.org via_cnt==1".
</programlisting>
</example>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>
Tracing Errors in Server Chains
</para>
</question>
<answer>
<para>
A request may pass any number of proxy servers on
its path to its destination. If an error occurs
in the chain, it is difficult for upstream troubleshooters
and/or users complaining to administrators to learn
more about error circumstances.
<application>ser
</application> does its best and displays extensive
diagnostics information in SIP replies. It allows
troubleshooters and/or users who report to troubleshooters
to gain additional knowledge about request processing
status.
This extended debugging information is part of the warning
header field. See <xref linkend="usingngrep"/> for an illustration
of a reply that includes such a warning header field. The header
field contains the following pieces of information:
<itemizedlist>
<listitem>
<para>
Server's IP Address -- good to identify
from which server in a chain the reply
came.
</para>
</listitem>
<listitem>
<para>
Incoming and outgoing URIs -- good to
learn for which URI the reply was
generated, as it may be rewritten
many times in the path. Particularly
useful for debugging of numbering plans.
</para>
</listitem>
<listitem>
<para>
Number of Via header fields in replied
request -- that helps in assessment of
request path length. Upstream clients would
not know otherwise, how far away in terms
of SIP hops their requests were replied.
</para>
</listitem>
<listitem>
<para>
Server's process id. That is useful for
debugging to discover situations when
multiple servers listen at the same
address.
</para>
</listitem>
<listitem>
<para>
IP address of previous SIP hop as seen by
the SIP server.
</para>
</listitem>
</itemizedlist>
</para>
<para>
If server administrator is not comfortable with
disclosing all this information, he can turn them
off using the <varname>sip_warning</varname> configuration
option.
</para>
<para>
A nice utility for debugging server chains is
<application>sipsak</application>,
SIP Swiss Army Knife, traceroute-like tool for SIP
developed at iptel.org. It allows you to send
OPTIONS request with low, increasing Max-Forwards
header-fields and follow how it propagates in
SIP network. See its webpage at
<ulink url="http://sipsak.berlios.de/">
http://sipsak.berlios.de/
</ulink>.
</para>
<example>
<title>Use of SIPSak for Learning SIP Path</title>
<programlisting>
[jiri@bat sipsak]$ ./sipsak -T -s sip:7271@iptel.org
warning: IP extract from warning activated to be more informational
0: 127.0.0.1 (0.456 ms) SIP/2.0 483 Too Many Hops
1: ?? (31.657 ms) SIP/2.0 200 OK
without Contact header
</programlisting>
<para>
Note that in this example, the second hop
server does not issue any warning header fields
in replies and it is thus impossible to display
its IP address in <application>
SIPsak</application>'s output.
</para>
</example>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>
Watching Server Health
</para>
</question>
<answer>
<para>
Watching Server's operation status in real-time may
also be a great aid for trouble-shooting.
<application>ser</application> has an excellent
facility, a FIFO server, which allows UNIX
tools to access server's internals. (It is
similar to how Linux tool access Linux kernel
via the proc file system.) The FIFO server
accepts commands via a FIFO (named pipe) and
returns data asked for. Administrators do not
need to learn details of the FIFO communication
and can serve themselves using a front-end
utility <application>serctl</application>.
Of particular interest for
monitoring server's operation are
<application>serctl</application>
commands
<command>ps</command> and
<command>moni</command>.
The former displays running
<application>ser</application>
processes, whereas the latter shows statistics.
</para>
<example>
<title>serctl ps command</title>
<para>
This example shows 10 processes running at a host.
The process 0, "attendant" watches child processes
and terminates all of them if a failure occurs in
any of them. Processes 1-4 listen at local
interface and processes 5-8 listen at Ethernet
interface at port number 5060. Process number
9 runs FIFO server, and process number 10
processes all server timeouts.
</para>
<programlisting>
[jiri@fox jiri]$ serctl ps
0 31590 attendant
1 31592 receiver child=0 sock=0 @ 127.0.0.1::5060
2 31595 receiver child=1 sock=0 @ 127.0.0.1::5060
3 31596 receiver child=2 sock=0 @ 127.0.0.1::5060
4 31597 receiver child=3 sock=0 @ 127.0.0.1::5060
5 31604 receiver child=0 sock=1 @ 195.37.77.101::5060
6 31605 receiver child=1 sock=1 @ 195.37.77.101::5060
7 31606 receiver child=2 sock=1 @ 195.37.77.101::5060
8 31610 receiver child=3 sock=1 @ 195.37.77.101::5060
9 31611 fifo server
10 31627 timer
</programlisting>
</example>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>
Is Server Alive
</para>
</question>
<answer>
<para>
It is essential for solid operation to know
continuously that server is alive. We've been
using two tools for this purpose.
<application>sipsak</application>
does a great job of "pinging" a server, which
may be used for alerting on unresponsive servers.
</para>
<para>
<application>monit</application> is
a server watching utility which alerts when
a server dies.
</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>
Dealing with DNS
</para>
</question>
<answer>
<para>
SIP standard leverages DNS. Administrators of
<application>ser</application> should
be aware of impact of DNS on server's operation.
Server's attempt to resolve an unresolvable address
may block a server process in terms of seconds. To be
safer that the server doesn't stop responding
due to being blocked by DNS resolving, we recommend
the following practices:
<itemizedlist>
<listitem>
<para>
Start a sufficient number of children processes.
If one is blocked, the other children will
keep serving.
</para>
</listitem>
<listitem>
<para>
Use DNS caching. For example, in Linux,
there is an <application>
nscd</application> daemon available for
this purpose.
</para>
</listitem>
<listitem>
<para>
Process transactions statefully if memory
allows. That helps to absorb retransmissions
without having to resolve DNS for each of
them.
</para>
</listitem>
</itemizedlist>
</para>
</answer>
</qandaentry>
<qandaentry id="logging">
<question>
<para>
Logging
</para>
</question>
<answer>
<para>
<application>ser</application> by default logs
to <application>syslog</application> facility.
It is very useful to watch log messages for
abnormal behavior. Log messages, subject to
<application>syslog</application> configuration
may be stored at different files, or even at remote
systems. A typical location of the log file is
<filename>/var/log/messages</filename>.
</para>
<note>
<para>
One can also use other <application>syslogd</application>
implementation. <application>metalog</application>
(<ulink url="http://metalog.sourceforge.net/">
http://metalog.sourceforge.net/
</ulink>)
features regular expression matching that enables
to filter and group log messages.
</para>
</note>
<para>
For the purpose of debugging configuration scripts, one may
want to redirect log messages to console not to pollute
syslog files. To do so configure <application>ser</application>
in the following way:
<itemizedlist>
<listitem>
<para>
Attach ser to console by setting <varname>fork=no</varname>.
</para>
</listitem>
<listitem>
<para>
Set explicitly at which address
<application>ser</application>
should be listening, e.g., <varname>listen=192.168.2.16</varname>.
</para>
</listitem>
<listitem>
<para>
Redirect log messages to standard error by setting
<varname>log_stderror=yes</varname>
</para>
</listitem>
<listitem>
<para>
Set appropriately high log level. (Be sure that you redirected logging
to standard output. Flooding system logs with many detailed messages
would make the logs difficult to read and use.) You can set the global
logging threshold value with the option <varname>debug=nr</varname>,
where the higher <varname>nr</varname> the more detailed output.
If you wish to set log level only for some script events, include
the desired log level as the first parameter of the
<command>log</command> action in your script.
The messages will be then printed if <command>log</command>'s
level is lower than the global threshold, i.e., the lower the more
noisy output you get.
<example>
<title>Logging Script</title>
<programlisting>
<xi:include href="../../examples/logging.cfg" parse="text"/>
</programlisting>
<para>
The following SIP message causes then logging output as shown
below.
</para>
<programlisting>
REGISTER sip:192.168.2.16 SIP/2.0
Via: SIP/2.0/UDP 192.168.2.33:5060
From: sip:113311@192.168.2.16
To: sip:113311@192.168.2.16
Call-ID: 00036bb9-0fd305e2-7daec266-212e5ec9@192.168.2.33
Date: Thu, 27 Feb 2003 15:10:52 GMT
CSeq: 101 REGISTER
User-Agent: CSCO/4
Contact: sip:113311@192.168.2.33:5060
Content-Length: 0
Expires: 600
</programlisting>
<programlisting>
[jiri@cat sip_router]$ ./ser -f examples/logging.cfg
Listening on
192.168.2.16 [192.168.2.16]::5060
Aliases: cat.iptel.org:5060 cat:5060
WARNING: no fork mode
0(0) INFO: udp_init: SO_RCVBUF is initially 65535
0(0) INFO: udp_init: SO_RCVBUF is finally 131070
0(17379) REGISTER received
0(17379) request for other domain received
</programlisting>
</example>
</para>
</listitem>
</itemizedlist>
</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>
Labeling Outbound Requests
</para>
</question>
<answer>
<para>
Without knowing, which pieces of script code a relayed
request visited, trouble-shooting would be difficult.
Scripts typically apply different processing to
different routes such as to IP phones and PSTN
gateways. We thus recommend to label outgoing
requests with a label describing the type of processing
applied to the request.
</para>
<para>
Attaching "routing-history" hints to relayed
requests is as easy as using the
<command>append_hf</command>
action exported by textops module. The following
example shows how different labels are attached
to requests to which different routing logic
was applied.
<example>
<title>"Routing-history" labels</title>
<programlisting>
# is the request for our domain?
# if so, process it using UsrLoc and label it so.
if (uri=~[@:\.]domain.foo") {
if (!lookup("location")) {
sl_send_reply("404", "Not Found");
break;
};
# user found -- forward to him and label the request
append_hf("P-hint: USRLOC\r\n");
} else {
# it is an outbound request to some other domain --
# indicate it in the routing-history label
append_hf("P-hint: OUTBOUND\r\n");
};
t_relay();
</programlisting>
<para>
This is how such a labeled requests looks
like. The last header field includes
a label indicating the script processed
the request as outbound.
</para>
<programlisting>
#
U 2002/09/26 02:03:09.807288 195.37.77.101:5060 -> 203.122.14.122:5060
SUBSCRIBE sip:rajesh@203.122.14.122 SIP/2.0.
Max-Forwards: 10.
Via: SIP/2.0/UDP 195.37.77.101;branch=53.b44e9693.0.
Via: SIP/2.0/UDP 203.122.14.115:16819.
From: sip:rajeshacl@iptel.org;tag=5c7cecb3-cfa2-491d-a0eb-72195d4054c4.
To: sip:rajesh@203.122.14.122.
Call-ID: bd6c45b7-2777-4e7a-b1ae-11c9ac2c6a58@203.122.14.115.
CSeq: 2 SUBSCRIBE.
Contact: sip:203.122.14.115:16819.
User-Agent: Windows RTC/1.0.
Proxy-Authorization: Digest username="rajeshacl", realm="iptel.org", algorithm="MD5", uri="sip:rajesh@203.122.14.122", nonce="3d924fe900000000fd6227db9e565b73c465225d94b2a938", response="a855233f61d409a791f077cbe184d3e3".
Expires: 1800.
Content-Length: 0.
P-hint: OUTBOUND.
</programlisting>
</example>
</para>
</answer>
</qandaentry>
</qandaset>
</section> <!-- operational practises -->
<section>
<title>HOWTOs</title>
<para>
This section is a "cookbook" for dealing with common tasks, such as
user management or controlling access to PSTN gateways.
</para>
<section>
<title>User Management</title>
<para>
There are two tasks related to management of SIP users:
maintaining user accounts and maintaining user contacts.
Both these jobs can be done using the
<application>serctl</application>
command-line tool. Also, the complimentary web
interface, <application>serweb</application>,
can be used for this purpose as well.
</para>
<para>
If user authentication is turned on, which is a highly
advisable practice, user account must be created before
a user can log in. To create a new user account, call the
<command>serctl add</command> utility
with username, password and email as parameters. It
is important that the environment <varname>SIP_DOMAIN</varname>
is set to your realm and matches realm values used in
your script. The realm value is used for calculation
of credentials stored in subscriber database, which are
bound permanently to this value.
<screen>
[jiri@cat gen_ha1]$ export SIP_DOMAIN=foo.bar
[jiri@cat gen_ha1]$ serctl add newuser secret newuser@foo.bar
MySql Password:
new user added
</screen>
</para>
<para><application>serctl</application> can
also change user's password or remove existing accounts
from system permanently.
<screen>
[jiri@cat gen_ha1]$ serctl passwd newuser newpassword
MySql Password:
password change succeeded
[jiri@cat gen_ha1]$ serctl rm newuser
MySql Password:
user removed
</screen>
</para>
<para>
User contacts are typically automatically uploaded by SIP phones
to server during registration process and administrators do not
need to worry about them. However, users
may wish to append permanent contacts to PSTN gateways
or to locations in other administrative domains.
To manipulate the contacts in such cases, use
<application>serctl ul</application>
tool. Note that this is the only correct way
to update contacts -- direct changes to back-end
MySql database do not affect server's memory. Also note,
that if persistence is turned off (usrloc "db_mode"
parameter set to "0"), all contacts are gone on server
reboot. Make sure that persistence is enabled if you
add permanent contacts.
</para>
<para>
To add a new permanent contact for a user, call
<application>serctl ul add <username>
<contact></application>. To delete
all user's contacts, call
<application>serctl ul rm <username></application>.
<application>serctl ul show <username></application>
prints all current user's contacts.
<screen>
[jiri@cat gen_ha1]$ serctl ul add newuser sip:666@gateway.foo.bar
sip:666@gateway.foo.bar
200 Added to table
('newuser','sip:666@gateway.foo.bar') to 'location'
[jiri@cat gen_ha1]$ serctl ul show newuser
<sip:666@gateway.foo.bar>;q=1.00;expires=1073741812
[jiri@cat gen_ha1]$ serctl ul rm newuser
200 user (location, newuser) deleted
[jiri@cat gen_ha1]$ serctl ul show newuser
404 Username newuser in table location not found
</screen>
</para>
</section> <!-- user management -->
<section>
<title>User Aliases</title>
<para>
Frequently, it is desirable for a user to have multiple
addresses in a domain. For example, a user with username "john.doe" wants to be
reachable at a shorter address "john" or at a numerical address
"12335", so that PSTN callers with digits-only key-pad can reach
him too.
</para>
<para>
With <application>ser</application>, you can maintain
a special user-location table and translate existing aliases to canonical
usernames using the <command>lookup</command>
action from usrloc module. The following script fragment demonstrates
use of <command>lookup</command> for this purpose.
<example>
<title>Configuration of Use of Aliases</title>
<programlisting>
if (!uri==myself) { # request not for our domain...
route(1); # go somewhere else, where outbound requests are processed
break;
};
# the request is for our domain -- process registrations first
if (method=="REGISTER") { route(3); break; };
# look now, if there is an alias in the "aliases" table; don't care
# about return value: whether there is some or not, move ahead then
lookup("aliases");
# there may be aliases which translate to other domain and for which
# local processing is not appropriate; check again, if after the
# alias translation, the request is still for us
if (!uri==myself) { route(1); break; };
# continue with processing for our domain...
...
</programlisting>
</example>
</para>
<para>
The table with aliases is updated using the
<application>serctl</application>
tool. <application>
serctl alias add <alias> <uri></application>
adds a new alias,
<application>serctl alias show <user></application>
prints an existing alias, and
<application>serctl alias rm <user></application>
removes it.
<screen>
[jiri@cat sip_router]$ serctl alias add 1234 sip:john.doe@foo.bar
sip:john.doe@foo.bar
200 Added to table
('1234','sip:john.doe@foo.bar') to 'aliases'
[jiri@cat sip_router]$ serctl alias add john sip:john.doe@foo.bar
sip:john.doe@foo.bar
200 Added to table
('john','sip:john.doe@foo.bar') to 'aliases'
[jiri@cat sip_router]$ serctl alias show john
<sip:john.doe@foo.bar>;q=1.00;expires=1073741811
[jiri@cat sip_router]$ serctl alias rm john
200 user (aliases, john) deleted
</screen>
</para>
<para>
Note that persistence needs to be turned on in usrloc
module. All changes to aliases will be otherwise lost
on server reboot. To enable persistence, set the
db_mode usrloc parameter to a non-zero value.
<programlisting>
# ....load module ...
loadmodule "modules/usrloc/usrloc.so"
# ... turn on persistence -- all changes to user tables are immediately
# flushed to mysql
modparam("usrloc", "db_mode", 1)
# the SQL address:
modparam("usrloc", "db_url","mysql://ser:secret@dbhost/ser")
</programlisting>
</para>
</section> <!-- user aliases -->
<section id="acl">
<title>Access Control (PSTN Gateway)</title>
<para>
It is sometimes important to exercise some sort of
access control. A typical use case is when
<application>ser</application> is used
to guard a PSTN gateway. If a gateway was not well guarded,
unauthorized users would be able to use it to terminate calls in PSTN,
and cause high charges to its operator.
</para>
<para>
There are few issues you need to understand when
configuring <application>ser</application>
for this purpose. First, if a gateway is built or configured to
accept calls from anywhere, callers may easily bypass your
access control server and communicate with the gateway
directly. You then need to enforce at transport layer
that signaling is only accepted if coming via
<application>ser</application> and
deny SIP packets coming from other hosts and port numbers.
Your network must be configured not to allow forged
IP addresses. Also, you need to turn on record-routing
to assure that all session requests will travel via
<application>ser</application>.
Otherwise, caller's devices would send subsequent SIP requests
directly to your gateway, which would fail because of transport
filtering.
</para>
<para>
Authorization (i.e., the process of determining who may call where)
is facilitated in <application>ser</application>
using <emphasis>group membership</emphasis> concept. Scripts make
decisions on whether a caller is authorized to make a call to
a specific destination based on user's membership in a group.
For example a policy may be set up to allow calls to international
destinations only to users, who are members of an "int" group.
Before user's group membership is checked, his identity
must be verified first. Without cryptographic verification of user's
identity, it would be impossible to assert that a caller really
is who he claims to be.
</para>
<para>
The following script demonstrates, how to configure <application>ser</application>
as an access control server for a PSTN gateway. The script verifies user
identity using digest authentication, checks user's privileges,
and forces all requests to visit the server.
<example>
<title>Script for Gateway Access Control</title>
<programlisting>
<xi:include href="../../examples/pstn.cfg" parse="text"/>
</programlisting>
</example>
</para>
<para>
Use the <application>serctl</application> tool to
maintain group membership.
<application>serctl acl grant <username> <group></application>
makes a user member of a group,
<application>serctl acl show <username></application> shows groups
of which a user is member, and
<application>serctl acl revoke <username> [<group>]</application>
revokes user's membership in one or all groups.
<screen>
[jiri@cat sip_router]$ serctl acl grant john int
MySql Password:
+------+-----+---------------------+
| user | grp | last_modified |
+------+-----+---------------------+
| john | int | 2002-12-08 02:09:20 |
+------+-----+---------------------+
</screen>
</para>
</section> <!-- access control -->
<section>
<title>Accounting</title>
<para>
In some scenarios, like termination of calls in PSTN, SIP administrators
may wish to keep track of placed calls. <application>ser</application>
can be configured to report on completed transactions. Reports are sent
by default to <application>syslog</application> facility.
Support for RADIUS and mysql accounting exists as well.
</para>
<para>
Note that <application>ser</application> is no way
call-stateful. It reports on completed transactions, i.e., after
a successful call set up is reported, it drops any call-related
state. When a call is terminated, transactional state for BYE request
is created and forgotten again after the transaction completes.
This is a feature and not a bug -- keeping only transactional
state allows for significantly higher scalability. It is then
up to the accounting application to correlate call initiation
and termination events.
</para>
<para>
To enable call accounting, tm and acc modules need to be loaded,
requests need to be processed statefully and labeled for
accounting. That means, if you want a transaction to be reported,
the initial request must have taken the path
"<command>setflag(X)</command>, <command>t_relay</command>"
in <application>ser</application> script. X must have the
value configured in <varname>acc_flag</varname>
configuration option.
</para>
<para>
Also note, that by default only transactions that initiate
a SIP dialog (typically INVITE) visit a proxy server.
Subsequent transactions are exchanged directly between
end-devices, do not visit proxy server and cannot be
reported. To be able to report on subsequent transactions,
you need to force them visit proxy server by turning
record-routing on.
</para>
<para>
<example>
<title>Configuration with Enabled Accounting</title>
<programlisting>
<xi:include href="../../examples/acc.cfg" parse="text"/>
</programlisting>
</example>
</para>
</section> <!-- accounting -->
<section>
<title>Reliability</title>
<para>
It is essential to guarantee continuous
service operation even under erroneous conditions,
such as host or network failure. The major issue in such
situations is transfer of operation to a backup
infrastructure and making clients use it.
</para>
<para>
The SIP standard's use of DNS SRV records has been
explicitly constructed to handle with server failures.
There may be multiple servers responsible for a domain
and referred to by DNS. If it is impossible to communicate
with a primary server, a client can proceed to another one.
Backup servers may be located in a different geographic
area to minimize risk caused by areal operational
disasters: lack of power, flooding, earthquake, etc.
<note>
<sidebar>
<para>Unless there are redundant DNS
servers, fail-over capability cannot be guaranteed.
</para>
</sidebar>
</note>
Unfortunately, at the moment of writing this documentation
(end of December 2002) only very few SIP products
actually implement the DNS fail-over mechanism. Unless
networks with SIP devices supporting this mechanism are
built, alternative mechanisms must be used to force
clients to use backup servers. Such a mechanism is
disconnecting primary server and replacing it with
a backup server locally.
It unfortunately precludes geographic dispersion and
requires network multihoming to avoid dependency on
single IP access. Another method is to update DNS
when failure of the primary server is detected.
The primary drawback of this method is its latency:
it may take long time until all clients learn to use
the new server.
</para>
<para>
The easier part of the redundancy story is replication of
<application>ser</application>
data. <application>ser</application>
relies on replication capabilities of its back-end database.
This works with one exception: user location database.
User location database is a frequently accessed table,
which is thus cached in server's memory to improve
performance. Back-end replication does not affect
in-memory tables, unless server reboots. To facilitate
replication of user location database,
server's SIP replication feature must be enabled
in parallel with back-end replication.
</para>
<para>
The design idea of replication of user location database
is easy: Replicate any successful REGISTER requests to
a peer server. To assure that digest credentials can
be properly verified, both servers need to use the same
digest generation secret and maintain synchronized time.
A known limitation of this method is it does not replicate
user contacts entered in another way, for example using
web interface through FIFO server.
The following script example shows configuration of
a server that replicates all REGISTERs.
<example>
<title>Script for Replication of User Contacts</title>
<programlisting>
<xi:include href="../../examples/replicate.cfg" parse="text"/>
</programlisting>
</example>
</para>
</section> <!-- reliability -->
<section>
<title>Stateful versus Stateless Forwarding</title>
<para>
<application>ser</application> allows both stateless
and stateful request processing. This memo explains what are pros and cons of
using each method. The rule of thumb is "stateless for scalability,
stateful for services". If you are unsure which you need, stateful
is a safer choice which supports more usage scenarios.
</para>
<para>
Stateless forwarding with the
<command>forward(uri:host, uri:port)</command> action
guarantees high scalability. It withstands high load and
does not run out of memory. A perfect use of stateless forwarding
is load distribution.
</para>
<para>
Stateful forwarding using the <command>t_relay()</command>
action is known to scale worse. It can quickly run out of memory and
consumes more CPU time. Nevertheless, there are scenarios which are
not implementable without stateful processing. In particular:
<itemizedlist>
<listitem>
<para>
<emphasis>Accounting</emphasis> requires stateful processing
to be able to collect transaction status and issue a single
report when a transaction completes.
</para>
</listitem>
<listitem>
<para>
<emphasis>Forking</emphasis> only works with stateful forwarding.
Stateless forwarding only forwards to the default URI out of the
whole destination set.
</para>
</listitem>
<listitem>
<para>
<emphasis>DNS resolution</emphasis>. DNS resolution may be
better served with stateful processing. If a request is forwarded
to a destination whose address takes long time to resolve,
a server process is blocked and unresponsive. Subsequent
request retransmissions from client will cause other processes
to block too if requests are processed statelessly. As a result,
<application>ser</application> will quickly
run out of available processes. With stateful forwarding,
retransmissions are absorbed and do not cause blocking of
another process.
</para>
</listitem>
<listitem>
<para>
<emphasis>Forwarding Services</emphasis>. All sort of services
with the "forward_on_event" logic, which rely on
<command>t_on_failure</command> tm
action must be processed statefully.
</para>
</listitem>
<listitem>
<para>
<emphasis>
Fail-over.
</emphasis>
If you wish to try out another destination, after a primary destination
failed you need to use stateful processing. With stateless processing
you never know with what status a forwarded request completed downstream
because you immediately release all processing information after the
request is sent out.
<note>
<para>
Positive return value of stateless
<command>forward</command> action only indicates that
a request was successfully sent out, and does not gain any knowledge
about whether it was successfully received or replied. Neither does
the return value of
the stateful <command>t_relay</command> action family
gain you this knowledge. However, these actions store transactional
context with which includes original request and allows you to
take an action when a negative reply comes back or a timer strikes.
See <xref linkend="replyprocessingsection"/> for an example script
which launches another
branch if the first try fails.
</para>
</note>
</para>
</listitem>
</itemizedlist>
</para>
</section> <!-- stateful vs. stateless -->
<section>
<title>Serving Multiple Domains</title>
<para>
<application>ser</application> can be configured to
serve multiple domains. To do so, you need to take the following steps:
<orderedlist>
<listitem id="createtable">
<para>
Create separate subscriber and location database table
for each domain served and name them uniquely.
</para>
</listitem>
<listitem>
<para>
Configure your script to distinguish between multiple
served domains. Use regular expressions for domain
matching as described in <xref linkend="redomainmatching"/>.
</para>
</listitem>
<listitem>
<para>
Update table names in usrloc and auth actions to reflect
names you created in <xref linkend="createtable"/>.
</para>
</listitem>
</orderedlist>
</para>
<para>
The latest <application>SER</application> release includes automated
multidomain management which greatly automates maintenance of multiple
domains. Ask our technical support for more help.
</para>
</section> <!-- multiple domains -->
<section id="missedcalls">
<title>Reporting Missed Calls</title>
<para>
<application>ser</application> can report missed
calls via <application>syslog</application> facility
or to mysql. Mysql reporting can be utilized by
<application>ser</application>'s
complementary web-interface, <application>serweb</application>.
(See more in <xref linkend="serweb"/>).
</para>
<para>
Reporting on missed calls is enabled by acc module.
There are two cases, on which you want to report. The first
case is when a callee is off-line. The other case is when
a user is on-line, but call establishment fails. There
may be many failure reasons (call cancellation, inactive phone,
busy phone, server timer, etc.), all of them leading to
a negative (>=300) reply sent to caller. The acc module
can be configured to issue a missed-call report whenever
a transaction completes with a negative status. Two following
script fragment deals with both cases.
</para>
<para>
First, it reports
on calls missed due to off-line callee status
using the <command>acc_request</command>
action. The action is wrapped in transactional
processing (<command>t_newtran</command>)
to guarantee that reports are not
duplicated on receipt of retransmissions.
</para>
<para>
Secondly, transactions to on-line users are marked
to be reported on failure. That is what the
<command>setflag(3)</command> action
is responsible for, along with the configuration option
"log_missed_flag". This option configures <application>ser</application>
to report on all transactions, which were marked
with flag 3.
<programlisting>
loadmodule("modules/tm/tm.so");
loadmodule("modules/acc/acc.so");
....
# if a call is labeled using setflag(3) and is missed, it will
# be reported
...
modparam("acc", "log_missed_flag", 3 );
if (!lookup("location")) {
# call invitations to off-line users are reported using the
# acc_request action; to avoid duplicate reports on request
# retransmissions, request is processed statefully (t_newtran,
# t_reply)
if ((method=="INVITE" || method=="ACK") && t_newtran() ) {
t_reply("404", "Not Found");
acc_request("404 Not Found");
break;
};
# all other requests to off-line users are simply replied
# statelessly and no reports are issued
sl_send_reply("404", "Not Found");
break;
} else {
# user on-line; report on failed transactions; mark the
# transaction for reporting using the same number as
# configured above; if the call is really missed, a report
# will be issued
setflag(3);
# forward to user's current destination
t_relay();
break;
};
</programlisting>
</para>
</section> <!-- missed calls -->
<section>
<title>NAT Traversal</title>
<para>
NATs are worst things that ever happened to SIP. These devices
are very popular because they help to conserve IP address space
and save money charged for IP addresses. Unfortunately, they
translate addresses in a way which is not compatible with SIP.
SIP advertises receiver addresses in its payload. The advertised
addresses are invalid out of NATed networks. As a result,
SIP communication does not work across NATs without extra
effort.
</para>
<para>
There are few methods that may be deployed to traverse NATs.
How proper their use is depends on the deployment scenario.
Unfortunately, all the methods have some limitations and
there is no straight-forward solution addressing all
scenarios. Note that none of these methods takes explicit
support in <application>ser</application>.
</para>
<para>
The first issue is whether SIP users are in control of
their NATs. If not (NATs are either operated by ISP or
they are sealed to prevent users setting them up), the
only method is use of a STUN-enabled phone. STUN is
a very simple protocol used to fool NAT in such a way,
they permit SIP sessions. Currently, we are aware of
one softphone (kphone) and one hardphone (snom) with
STUN support, other vendors are working on STUN support
too. Unfortunately, STUN gives no NAT traversal
guarantee -- there are types of NATs, so called
symmetric NATs, over which STUN fails to work.
<note>
<para>
There is actually yet another method to address
SIP-unaware, user-uncontrolled NATs. It is based
on a proxy server, which relays all signaling and
media and mangles packets to make them more
NAT-friendly. The very serious problem with this
method is it does not scale.
</para>
</note>
</para>
<para>
If users are in control of their own NAT, as typically residential
users are, they can still use STUN. However, they may use other
alternatives too. One of them is to replace their NAT with
a SIP-aware NAT. Such NATs have built-in SIP awareness,
that patches problems caused by address translations. Prices
of such devices are getting low and there are available
implementations (Intertex, Cisco/PIX). No special support
in phones is needed.
</para>
<para>
Other emerging option is UPnP. UPnP is a protocol that allows
phones to negotiate with NAT boxes. You need UPnP support in
both, NAT and phones. As UPnP NATs are quite affordable,
costs are not an obstacle. Currently, we are aware of one
SIP phone (SNOM) with UPnP support.
</para>
<para>
Geeks not wishing to upgrade their firewall to a SIP-aware or
UPnP-enabled one may try to configure static address translation.
That takes phones with configuration ability to use fixed port
numbers and advertise outside address in signaling. Cisco phones
have this capability, for example. The NAT devices need to
be configured to translate outside port ranges to the
ranges configured in phones.
</para>
</section> <!-- NAT traversal -->
<section>
<title>Using Only Latest User's Contact for Forwarding
</title>
<para>
In some scenarios, it may be beneficial only to use only one
registered contact per user. If that is the case, setting
registrar module's parameter <varname>append_branches</varname>
to 1 will eliminate forking and forward all requests only
to a single contact. If there are multiple contacts, a contact
with highest priority is chosen. This can be changed to
the "freshest" contact by setting module parameter's
<varname>desc_time_order</varname> to 1.
</para>
</section>
<section>
<title>Authentication Policy: Prevention of Unauthorized Domain
Name Use in From and More</title>
<para>
Malicious users can claim a name of domain, to which they do
not administratively belong, in From header field. This
behavior cannot be generally prevented. The reason is
that requests with such a faked header field do not need
to visit servers of the domain in question. However, if they
do so, it is desirable to assure that users claiming
membership in a domain are actually associated with it.
Otherwise the faked requests would be relayed and appear
as coming from the domain, which would increase
credibility of the faked address and decrease credibility of
the proxy server.
</para>
<para>
Preventing unauthorized domain name use in relayed requests
is not difficult.
One needs to authenticate each request with name of the
served domain in From header field. To do so, one can
search for such a header field using <command>search</command>
action (textops module) and force authentication if the
search succeeds.
<note>
<para>
A straight-forward solution might be to authenticate
ALL requests. However, that only works in closed
networks in which all users have an account in the
server domain. In open networks, it is desirable to permit
incoming calls from callers from other domains without
any authentication. For example, a company may wish
to accept calls from unknown callers who are
new prospective customers.
</para>
</note>
<programlisting>
# does the user claim our domain "foo.bar" in From?
if (search("^(f|From):.*foo.bar")) {
# if so, verify credential
if (!proxy_authorize("foo.bar", "subscriber")) {
# don't proceed if credentials broken; challenge
proxy_challenge("foo.bar", "0");
break;
};
};
</programlisting>
</para>
<para>
In general, the authentication policy may be very rich. You may not
forget each request deserves its own security and you need to
decide whether it shall be authenticated or not. As mentioned
above, in closed networks, you may want to authenticate absolutely
every request. That however prohibits traffic from users from
other domains. A pseudo-example of a reasonable policy is attached:
it looks whether a request is registration, it claims to originate
from our domain in From header field, or is a local request to
another domain.
<programlisting>
# (example provided by Michael Graff on [serusers] mailing list
if (to me):
if register
www_authorize or fail if not a valid register
done
if claiming to be "From" one of the domains I accept registrations for
proxy_authorize
done
if not to me (I'm relaying for a local phone to an external address)
proxy_authorize
done
</programlisting>
</para>
<para>
You also may want to apply additional restriction to how
digest username relates to usernames claimed in From and
To header fields. For example, the <command>check_to</command>
action enforces the digest id to be equal to username
in To header fields. That is good in preventing someone
with valid credentials to register as someone else
(e.g., sending a REGISTER with valid credentials of
"joe" and To belonging to "alice"). Similarly,
<command>check_from</command> is used
to enforce username in from to equal to digest id.
<note>
<para>
There may be a need for a more complex relationship
between From/To username and digest id. For example,
providers with an established user/password database
may wish to keep using it, whereas permitting users
to claim some telephone numbers in From. To address
such needs generally, there needs to be a 1:N mapping
between digest id and all usernames that are acceptable
for it. This is being addressed in a newly contributed
module "domain", which also addresses more generally
issues of domain matching for multidomain scenarios.
</para>
</note>
</para>
<para>
Other operational aspect affecting the authentication policy
is guarding PSTN gateways (see <xref linkend="acl"/>). There
may be destinations that are given away for free whereas
other destinations may require access control using
group membership, to which authentication is a prerequisite.
</para>
</section> <!-- authentication policy, faked froms -->
<section>
<title>Connecting to PBX Voicemail Using a Cisco Gateway</title>
<para>
In some networks, administrators may wish to utilize their
PBX voicemail systems behind PSTN gateways. There is a practical problem
in many network settings: it is not clear for whom a call to
voicemail is. If voicemail is identified by a single number,
which is then put in INVITE's URI, there is no easy way to
learn for whom a message should be recorded. PBX voicemails
utilize that PSTN protocols signal the number of originally
called party. If you wish to make the PBX voicemail work,
you need to convey the number in SIP and translate it in
PSTN gateways to its PSTN counterpart.
</para>
<para>
There may be many different ways to achieve this scenario. Here
we describe the proprietary mechanism Cisco gateways use and how to
configure <application>ser</application> to
make the gateways happy. Cisco gateways expect the number
of originally called party to be located in proprietary
<varname>CC-Diversion</varname> header field. When a SIP
INVITE sent via a PSTN gateway to PBX voicemail has number
of originally called party in the header field, the voicemail
system knows for whom the incoming message is. That is at least
true for AS5300/2600 with Cisco IOS 12.2.(2)XB connected to
Nortel pbxs via PRI. (On the other hand, 12.2.(7b) is known
not to work in this scenario.)
</para>
<para>
<application>ser</application> needs then to
be configured to append the <varname>CC-Diversion</varname>
header field name for INVITEs sent to PBX voicemail.
The following script shows that: when initial forwarding
fails (nobody replies, busy is received, etc.), a new branch
is initiated to the pbx's phone number.
<command>append_urihf</command> is used to
append the <varname>CC-Diversion</varname> header field. It
takes two parameters: prefix, which includes header name,
and suffix which takes header field separator.
<command>append_urihf</command> inserts
original URI between those two.
<example>
<title>Forwarding to PBX/Voicemail via Cisco Gateways</title>
<programlisting>
<xi:include href="../../examples/ccdiversion.cfg" parse="text"/>
</programlisting>
</example>
</para>
</section>
</section> <!-- howtos -->
<section>
<title>Troubleshooting</title>
<para>
This section gathers practices how to deal with errors
known to occur frequently. To understand how to watch
SIP messages, server logs, and in general how to
troubleshoot, read also <xref linkend="operationalpractices"/>.
</para>
<qandaset>
<qandaentry>
<question>
<para>
SIP requests are replied by <application>ser</application> with
"483 Too Many Hops" or "513 Message Too Large"
</para>
</question>
<answer>
<para>
In both cases, the reason is probably an error in
request routing script which caused an infinite loop.
You can easily verify whether this happens by
watching SIP traffic on loopback interface. A typical
reason for misrouting is a failure to match local
domain correctly. If a server fails to recognize
a request for itself, it will try to forward it
to current URI in believe it would forward them
to a foreign domain. Alas, it forwards the request
to itself again. This continues to happen until
value of max_forwards header field reaches zero
or the request grows too big. Solutions is easy:
make sure that domain matching is correctly
configured. See <xref linkend="domainmatching"/>
for more information how to get it right.
</para>
</answer>
</qandaentry>
<qandaentry id="msmbug">
<question>
<para>
Windows Messenger authentication fails.
</para>
</question>
<answer>
<para>
The most likely reason for this problem is a bug
in Windows Messenger. WM only authenticates if
server name in request URI equals authentication
realm. After a challenge is sent by SIP server,
WM does not resubmit the challenged request at all
and pops up authentication window again.
If you want to authenticate WM, you need to
set up your realm value to equal server name.
If your server has no name, IP address can be used
as realm too. The realm value is configured in
scripts as the first parameter of all
<command>{www|proxy}_{authorize|challenge}</command>
actions.
</para>
</answer>
</qandaentry>
<qandaentry id="mhomed">
<question>
<para>
On a multihomed host, forwarded messages carry other
interface in Via than used for sending, or messages
are not sent and an error log is issued "invalid
sendtoparameters one possible reason is the server
is bound to localhost".
</para>
</question>
<answer>
<para>
Set the configuration option <varname>mhomed</varname>
to "1". <application>ser</application>
will then attempt to calculate the correct interface.
It's not done by default as it degrades performance
on single-homed hosts or multi-homed hosts that are
not set-up as routers.
</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>
I receive "ERROR: t_newtran: transaction already in process" in my logs.
</para>
</question>
<answer>
<para>
That looks like an erroneous use of tm module in script.
tm can handle only one transaction per request. If you
attempt to instantiate a transaction multiple times,
<application>ser</application> will complain.
Anytime any of <command>t_newtran</command>,
<command>t_relay</command> or
<command>t_relay_to_udp</command> actions is
encountered, tm attempts to instantiate a transaction.
Doing so twice fails. Make sure that any of this
commands is called only once during script execution.
</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>
I try to add an alias but
<command>serctl</command>
complains that table does not exist.
</para>
</question>
<answer>
<para>
You need to run <application>ser</application>
and use the command
<command>lookup("aliases")</command>
in its routing script. That's because the table
of aliases is
stored in cache memory for high speed. The cache
memory is only set up when the
<application>ser</application>
is running and configured to use it. If that is
not the case,
<application>serctl</application>
is not able to manipulate the aliases table.
</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>I started <application>ser</application> with
<varname>children=4</varname> but many more processes
were started. What is wrong?
</para>
</question>
<answer>
<para>
That's ok. The <varname>children</varname> parameter defines
how many children should process each transport protocol in
parallel. Typically, the server listens to multiple protocols
and starts other supporting processes like timer or FIFO
server too. Call <application>serctl ps</application> to watch
running processes.
</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>
I decided to use a compiled version of <application>ser</application>
but it does not start any more.
</para>
</question>
<answer>
<para>
You probably kept the same configuration file, which tries to load modules
from the binary distribution you used previously. Make sure that modules
paths are valid and point to where you compiled <application>ser</application>.
Also, watch logs for error messages "ERROR: load_module: could not open
module".
</para>
</answer>
</qandaentry>
</qandaset>
</section> <!-- troubleshooting -->
</section>
|