2444f154e3c8afafd61158382b740b3275b35606
[sip-router] / etc / ser-oob.cfg
1 #
2 # $Id$
3 #
4 #
5 # Applicability of this Configuration File
6 # ----------------------------------------
7 #
8 # This is default SER script as used for example at the iptel.org
9 # SIP service; it can deal with NATs, terminate calls to a PSTN
10 # gateway, and it implements a couple of basic signaling features
11 # (few types of call forwarding). In this scenario you may have
12 # multiple SIP proxies sharing one database for accessing provisioned
13 # data, which are maintained for example using serweb. The proxy
14 # servers also share write-access to user location database (and
15 # keeps a full cache of all usrloc entries synchronized using
16 # multicast).
17 #
18 # If you look for a simpler version with a lot less dependencies
19 # please refer to the ser-basic.cfg file in your SER distribution.
20 #
21 # Requirements:
22 # ---------------
23 # running DB, running RTP proxy, one public IP address
24 # for SIP service, one private IP address for administrative purposes;
25 # optional: IP address of a PSTN gateway
26 #
27 # HOWTOs:
28 # ---------
29 # To get this config running you need to execute the following commands
30 # with the new serctl (the capital word are just place holders):
31 #
32 #    $ ser_ctl domain add DOMAINNAME
33 #    $ ser_ctl user add USERNAME@DOMAINNAME -p PASSWORD
34 #
35 # If you want to have P-Asserted-ID header for your user
36 #
37 #    $ ser_attr add uid=UID asserted_id="PID"
38 #
39 # If you want to have (PSTN) gateway support:
40 #
41 #    $ ser_db add attr_types name=gw_ip rich_type=string raw_type=2 \
42 #      description="The gateway IP for the default ser.cfg" default_flags=33
43 #    $ ser_attr add global gw_ip=GATEWAY-IP
44 #
45 # Alternatively, you can simple uncomment the relevant line in this file
46 # right at the beginning of the main route.
47 #
48 # You can also use serweb to set all the values above.
49 #
50 # Users with permission to call PSTN using this script must have
51 # the $gw_acl attribute set properly, and shall have $asserted_id
52 # set to indicate their caller-id for calls to PSTN. For inbound
53 # calls from PSTN, additional aliases may be also set.
54 #
55 # Warning:
56 # -----------
57 # If this file is installed on Debian from package 'ser-oob' then some
58 # options in this configuration file may be set by post-installation
59 # script, according to values entered by user at installation time in
60 # debconf configuration. These values are then applied automatically to
61 # this file each time the 'ser-oob' package is upgraded or reconfigured by
62 # calling 'dpkg-reconfigure ser-oob'.
63 #
64 # The parts of this configuration file that may be altered by debconf are
65 # enclosed between '#DEBCONF-something-START' and '#DEBCONF-something-END'
66 # comment marks. Please do not remove them.
67 #
68 #
69 # TODO (Future possible improvements):
70 # ---------------------------------------
71 # * protocol tuning
72 #   - AVP-based diversion for call-forwarding (as opposed to specialized
73 #     module)
74 #   - add Date header in 200s to REGISTERs (to be packaged with NTP!)
75 # * more security:
76 #   - pike/rate-limit
77 #   - identity
78 #   - TLS
79 #   - permissions
80 #   - Re-name all internal headers so that they start with a common prefix,
81 #     such as P-SER and then wipe all such headers from requests received
82 #     from untrusted sources, such as the user agents or foreign proxy
83 #     servers
84 # * refined DB use (e.g., flatstore for acc)
85 # * miscellanous:
86 #  - dialog module for monitoring purposes
87 #  - more extensive logging using xlog (controlled by gflags/gAVPs)
88 # * leveraging 2.1 features:
89 #  - removal of private IP address (it takes a multicast-specific
90 #    command which will allow OS to determine source IP address)
91 #  - timer route:
92 #     * don't use exec (it takes domain.reload as script command)
93 #     * compare last-stored timestamp with current timestamp (it takes
94 #       assignment of gAVPs)
95 #     * check multicast REGISTERs for their TTL (this is a simple and
96 #       effective security check to prevent remote multicast messages
97 #       to damage our traffic)
98 #  - numerous fine-tuning parameters which are only available in 2.1
99 #   (mlock_pages, dns_try_naptr, etc.)
100 #  - better support for preloaded routes with domain name
101 #
102 # Security considerations:
103 # ------------------------
104 # The script has been tested against security leaks, but it comes
105 # under terms of GPL "as is" without any warranties; better check
106 # yourself that:
107 # - IP based authentication of PSTN gateway and multicast REGISTERs
108 #   is compliant to your network setup and security policy.
109 # - Multiple gateway IPs can't be provisioned as security checks
110 #   are applied only to one.
111 #
112 # Licensing
113 # ----------
114 # Copyright (C) 2005-2008 iptelorg GmbH
115 # This file is part of SER, a free SIP server. It is available under the
116 # terms of the  GNU General Public License.
117 # Numerous folks have contributed to this file, including but not limited
118 # to Andrei, Jan, Jiri, Michal, Miklos, Nils.
119 #
120 #
121 # .... that's it, enough of yadiyada, here the real config begins!
122
123
124 # ----------- Global Configuration Parameters -------------------------------
125
126 #debug=3    # debug level (cmd line: -ddd)
127 #memdbg=10  # memory debug log level
128 #memlog=10  # memory statistics log level
129 #log_facility=LOG_LOCAL0 # the facility used for logging (see syslog(3))
130
131 #DEBCONF-SERVERID-START
132 server_id=0
133 #DEBCONF-SERVERID-END
134
135 # Uncomment these lines to enter debugging mode or start SER with
136 # ser -ED
137 #
138 #fork=no
139 #log_stderror=yes
140
141 check_via=no            # (cmd. line: -v)
142 dns=no                  # (cmd. line: -r)
143 rev_dns=no              # (cmd. line: -R)
144 #port=5060
145 #children=4
146 #user=ser
147 #group=ser
148 #disable_core=yes       # disables core dumping
149 open_files_limit=20480  # sets the open file descriptors limit
150 #mhomed=yes             # usefull for multihomed hosts, small performance
151                         # penalty
152 disable_tcp=no          # be conservative about enabling TCP -- it can
153                         # degrade performance a lot
154 #tcp_accept_aliases=yes # accepts the tcp alias via option
155 phone2tel=no            # ignore user=phone in request-URIs -- otherwise
156                         # these URIs would be interpreted as equivalent
157                         # to TEL URIs, and their lookup would fail in URI
158                         # database
159 reply_to_via=no
160 # public IP address
161 #DEBCONF-LISTEN-START
162 listen=127.0.0.1
163 #DEBCONF-LISTEN-END
164 listen=224.0.1.75       # sip.mcast.net for REGISTER replication
165 # administrative interface -- needed for example for multicast source
166 # or XML-RPC
167 #DEBCONF-LISTEN_ADMIN-START
168 listen=udp:127.0.0.1
169 #DEBCONF-LISTEN_ADMIN-END
170
171 #listen=tls:127.0.0.1:5061
172
173 mlock_pages=yes
174 shm_force_alloc=yes
175 real_time=7
176
177 # ------------------- DNS Parameters ----------------------------------------
178 # (see doc/dns.txt for more details)
179 #
180 # minimum timeouts
181 dns_retr_time=1
182 dns_retr_no=1
183 dns_servers_no=1
184 dns_use_search_list=no
185 dns_try_ipv6=no
186 # dns cache & failover
187 use_dns_cache=on
188 use_dns_failover=on
189 # dns_cache_flags=0
190 dns_cache_negative_ttl=300
191 dns_cache_min_ttl=60
192 dns_cache_max_ttl=86400 # 1 day
193 dns_cache_mem=2048 # 2 MB
194 dns_cache_gc_interval=60  # garbage collection every minute
195 # ser 2.1 specific options
196 # dns_try_naptr=yes
197 # dns_srv_lb=yes  # srv based load balancing
198 # dns_udp_pref=3  # prefer udp (when resolving naptr record)
199 # dns_tcp_pref=2  # if no udp availbale accept tcp (for naptr)
200 # dns_tls_pref=-1 # ignore / don't accept tls (for naptr)
201 # dns_cache_delete_nonexpired=no
202
203 # ------------------- Blacklist Parameters ----------------------------------
204 # (see doc/dst_blacklist.txt for more details)
205 #
206 use_dst_blacklist=on
207 dst_blacklist_mem=1024 # 1 MB
208 dst_blacklist_expire=300  # blacklist default time
209 dst_blacklist_gc_interval=150 # 2.5 min
210 # for ser 2.1 to the above add tm blst_503* parameters and/or use the
211 # blst module (see NEWS)
212
213 # ------------------- TCP Parameters ----------------------------------------
214 # (see NEWS for more details)
215 tcp_connection_lifetime=3600
216 #tcp_max_connections=10240  # default is 2048
217 tcp_connect_timeout=1
218
219 # ------------------- TLS Parameters ----------------------------------------
220
221 # Enable TLS hooks so that the TLS module can be used
222 tls_enable=yes
223
224 # -------------------- Custom Parameters ------------------------------------
225 # These parameters can be modified runtime via RPC interface,
226 # read the documentation of cfg_rpc module.
227
228 # Session Timer parameters, RFC 4028
229 #
230 # Default session interval used by the proxy if the UAC does not support
231 # session timer. Set it to "0" to disable session timer proxy support.
232 #
233 session_timer.default = "1800" desc "default session interval (in s)"
234 #
235 # Minimum session interval accepted by the proxy, it must not be less
236 # than 90 seconds.
237 #
238 session_timer.min_se = "90" desc "minimum session interval (in s)"
239
240
241 # ------------------ Module Loading -----------------------------------------
242
243 loadpath "/usr/lib/ser/modules"
244
245 # load a SQL database for authentication, domains, user AVPs etc.
246 loadmodule "mysql"
247 #loadmodule "postgres"
248
249 loadmodule "sl"
250 loadmodule "tm"
251 loadmodule "rr"
252 loadmodule "maxfwd"
253 loadmodule "usrloc"
254 loadmodule "registrar"
255 loadmodule "xlog"
256 loadmodule "textops"
257 loadmodule "ctl"
258 loadmodule "auth"
259 loadmodule "auth_db"
260 loadmodule "gflags"
261 loadmodule "domain"
262 loadmodule "uri_db"
263 loadmodule "avp"
264 loadmodule "avp_db"
265 loadmodule "acc_db"
266 #loadmodule "xmlrpc"
267 loadmodule "options"
268 loadmodule "sanity"
269 loadmodule "nathelper"
270 loadmodule "uri"
271 loadmodule "speeddial"
272 loadmodule "timer"
273 loadmodule "db_ops"
274 loadmodule "exec"
275 loadmodule "cfg_rpc"
276 loadmodule "eval"
277 #loadmodule "tls"
278
279 # ----------------- Declaration of Script Flags -----------------------------
280 flags
281   FLAG_ACC            : 1, # the request will be recorded by ACC
282   FLAG_FAILUREROUTE   : 2, # we are operating from the failure route
283   FLAG_NAT            : 3, # the UAC is behind a NAT
284   FLAG_REPL_ENABLED   : 4, # REGISTER replication is enabled if set
285   FLAG_TOTAG          : 5, # request has a To tag
286   FLAG_PSTN_ALLOWED   : 6, # the user is allowed to use the PSTN
287   FLAG_DONT_RM_CRED   : 7, # do not remove the credentials
288   FLAG_AUTH_OK        : 8, # authentication succeeded
289   FLAG_SERWEB_RSVD1   : 9, # bit reserved for use with serweb
290   FLAG_SERWEB_RSVD2   : 10, # bit reserved for use with serweb
291   FLAG_SESSIONTIMER   : 11, # indicates that the UAC supports Session Timer
292   FLAG_RR_DONE        : 12, # the request got already one RR header
293   FLAG_RTP_PROXY      : 13; # the RTP proxy is turned on
294
295 avpflags
296   dialog_cookie;            # attribute will be stored in Route headers
297
298 # ----------------- Module-specific Parameters ------------------------------
299
300 # path to the database
301 #
302 #DEBCONF-DBURL-START
303 modparam("speeddial|auth_db|usrloc|domain|uri_db|gflags|avp_db|db_ops",
304          "db_url", "mysql://ser:heslo@127.0.0.1/ser")
305 #DEBCONF-DBURL-END
306
307 # specify the path to your database for accounting
308 #DEBCONF-DBURLACC-START
309 modparam("acc_db", "db_url", "mysql://ser:heslo@127.0.0.1/ser")
310 #DEBCONF-DBURLACC-END
311
312
313 # -- usrloc --
314
315 # Database access mode: 0 -- memory cached, 1 -- write through,
316 # 2 -- delayed write.  1 is generally safer than 2.  2 can help
317 # to survive peaks in load.  However, it creates delayed peaks that can
318 # impair request-processing latency later (usrloc would have to be
319 # re-redesigned more lock-free to avoid it).
320 #DEBCONF-DBMODE-START
321 modparam("usrloc", "db_mode", 1)
322 #DEBCONF-DBMODE-END
323
324 # Don't delete expired records from database on a per-contact basis -- that
325 # results in bulky DB operations and can lead to synchronization issues
326 # in server farm when for a time a server doesn't obtain re-reregistrations
327 modparam("usrloc","db_skip_delete",1)
328
329
330 # -- registrar --
331
332 # Maximum expires time.  Forces users to re-register every 10 min.
333 modparam("registrar", "max_expires", 600)
334
335 # Minimum expires time. Even if they try, clients cannot register
336 # for a shorter time than this.
337 modparam("registrar", "min_expires", 240)
338
339 # Identify natted contacts using a flag.
340 modparam("registrar", "load_nat_flag", "FLAG_NAT")
341 modparam("registrar", "save_nat_flag", "FLAG_NAT")
342
343 # Maximum number of contacts.
344 modparam("registrar", "max_contacts", 10)
345
346
347 # -- auth --
348
349 #modparam("auth_db", "calculate_ha1", yes)
350 #modparam("auth_db", "password_column", "password")
351
352 # Minimize replay-attack window.
353 modparam("auth", "nonce_expire", 10)
354
355 # Enable/disable extra authentication checks using the following modparams.
356 # The values are: 1 -- Request-URI, 2 -- Call-ID, 4 -- From tag,
357 # 8 -- source IP. The options are disabled by default.
358
359 # For REGISTER requests we hash the Request-URI, Call-ID, and source IP of the
360 # request into the nonce string. This ensures that the generated credentials
361 # cannot be used with another registrar, user agent with another source IP
362 # address or Call-ID. Note that user agents that change Call-ID with every
363 # REGISTER message will not be able to register if you enable this.
364 #modparam("auth", "auth_checks_register", 11)
365
366 # For dialog-establishing requests (such as the original INVITE, OPTIONS, etc)
367 # we hash the Request-URI and source IP. Hashing Call-ID and From tags takes
368 # some extra precaution, because these checks could render some UA unusable.
369 #modparam("auth", "auth_checks_no_dlg", 9)
370
371 # For mid-dialog requests, such as re-INVITE, we can hash source IP and
372 # Request-URI just like in the previous case. In addition to that we can hash
373 # Call-ID and From tag because these are fixed within a dialog and are
374 # guaranteed not to change. This settings effectively restrict the usage of
375 # generated credentials to a single user agent within a single dialog.
376 #modparam("auth", "auth_checks_in_dlg", 15)
377
378 # Deal with clients who can't do qop properly
379 modparam("auth", "qop", "")
380 #DEBCONF-AUTHSECRET-START
381 modparam("auth", "secret", "aqwedrftredswqwddcft")
382 #DEBCONF-AUTHSECRET-END
383
384
385 # -- rr --
386
387 # Add value to lr param to make some broken UAs happy.
388 modparam("rr", "enable_full_lr", 1)
389
390 # Limit the length of the AVP cookie to necessary attributes only
391 modparam("rr", "cookie_filter", "(account|uac_nat|stimer)")
392
393 # You probably do not want that someone can simply read and change
394 # the AVP cookie in your Routes, thus should really change this
395 # secret value below
396 modparam("rr", "cookie_secret", "sgsatewgdbsnmpoiewh")
397
398 # The ftag Route parameter may be used to easily determine if a BYE
399 # is coming from caller or callee, but we prefer shorter messages
400 modparam("rr", "append_fromtag", 0)
401
402
403 # -- gflags --
404
405 # Load global attributes.
406 modparam("gflags", "load_global_attrs", 1)
407
408
409 # -- domain --
410
411 # Load domain attributes.
412 modparam("domain", "load_domain_attrs", 1)
413
414
415 # -- ctl --
416
417 # By default, ctl listens on unixs:/tmp/ser_ctl if no other address is
418 # specified in modparams; this is also the default for sercmd.
419 modparam("ctl", "binrpc", "unixs:/tmp/ser_ctl")
420 # Listen on the "standard" fifo for backward compatibility.
421 modparam("ctl", "fifo", "fifo:/tmp/ser_fifo")
422 # Listen on tcp on localhost.
423 #modparam("ctl", "binrpc", "tcp:localhost:2046")
424
425
426 # -- acc_db --
427
428 # Failed transactions (those with negative responses) should be logged, too.
429 modparam("acc_db", "failed_transactions", 1)
430
431 # If you don't want to have accounting entries written into the database,
432 # comment the next line out.
433 modparam("acc_db", "log_flag", "FLAG_ACC")
434
435 # if you would like to customize your CDRs, do it here....
436 #modparam("acc_db", "attrs",
437 #         "$f.sop_billing_category,$f.isPrepaidCustomer,$f.sop_cf_orig_uid")
438
439
440 # -- tm --
441
442 # Do not restart the resend timer with each reply. (See INBOUND route
443 # below.)
444 modparam("tm", "restart_fr_on_each_reply", 0)
445
446
447 # -- xmlrpc --
448
449 # Use a sub-route. This is a lot safer then relying on the request method
450 # to distinguish HTTP from SIP
451 #modparam("xmlrpc", "route", "RPC");
452
453
454 # -- nathelper --
455
456 # RTP Proxy address
457 #DEBCONF-RTTPPROXY-START
458 modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:22222")
459 #DEBCONF-RTTPPROXY-END
460
461 # TCP keepalives as simple as CRLF
462 modparam("nathelper", "natping_crlf", 0)
463
464 # How often to send a NAT ping. Set this to 0 to turn NAT ping off.
465 #DEBCONF-NATPING_INTERVAL-START
466 modparam("nathelper", "natping_interval", 15)
467 #DEBCONF-NATPING_INTERVAL-END
468
469 # Only ping contacts that have the NAT flag set.
470 modparam("nathelper", "ping_nated_only", 1)
471
472 # Send an OPTIONS SIP request as NAT ping. If this is not set, a simple
473 # 4-byte ping is used.
474 modparam("nathelper", "natping_method", "OPTIONS")
475
476 # Temporary statefull natping test (only in future versions)
477 #modparam("nathelper", "natping_stateful", 1)
478
479
480 # -- exec --
481 modparam("exec", "time_to_kill", 200);
482 modparam("exec", "setvars", 0);
483
484 # -- timer --
485
486 # Register route ON_1MIN_TIMER to be called every minute.
487 modparam("timer", "declare_timer",
488          "ON_1MIN_TIMER=ON_1MIN_TIMER,60000,slow,enable");
489
490 # -- tls --
491 #modparam("tls", "config", "tls.cfg");
492
493 # -- db_ops --
494
495 modparam("db_ops", "declare_handle", "reload")
496
497
498 # -------------------------  Request Routing Logic --------------------------
499
500 # Main request route.
501 #
502 # Each request starts here.
503 #
504 route
505 {
506         # if you have a PSTN gateway just un-comment the follwoing line and
507         # specify the IP address of it to route calls to it.
508         #$gw_ip = "1.2.3.4"
509
510         # Alternatively (even better), set it as global persistent parameter
511         # using serweb or ser_attrs). If using a PSTN GW, per-subscriber
512         # options must ($gw_acl) or may (asserted_id) be set to enable calls
513         # to PSTN. If email-like URIs are used, having a URI alias for
514         # processing incoming PSTN-to-ip requests may be useful, too.
515         # Important: the script is assuming one global pstn-gw for all
516         # domains! Failure to allow gw_ip to be a domain-specic attribute
517         # would result in security gaps (onsend_route checks only for one
518         # gateway).
519
520         # First, do some initial sanity checks.
521         route(INIT);
522
523         # Bypass the rest of the script for CANCELs if possible.
524         route(CATCH_CANCEL);
525
526         # Check if the request is routed via Route header.
527         route(LOOSE_ROUTE);
528
529         # Look up domain IDs
530         route(DOMAIN);
531
532         # Answer OPTIONS requests to our system.
533         route(OPTIONS_REPLY);
534
535         # Enforce domain policy.
536         route(DOMAIN_POLICY);
537
538         # Handle REGISTER requests.
539         route(REGISTRAR);
540
541         # From here on we want to know who is calling.
542         route(AUTHENTICATION);
543
544         # We are finished with all the precaution work -- let's
545         # try to locate the callee. The first route that matches
546         # "wins" and relays the request.  If none matches, SER will
547         # send a 404.
548
549         # Check if we should be outbound proxy for a local user.
550         route(OUTBOUND);
551
552         # Redirect in case user dialed a speed dial entry.
553         route(SPEEDDIAL);
554
555         # Place various site-specific routes here.
556         route(SITE_SPECIFIC);
557
558         # Check if the request is for a local user.
559         route(INBOUND);
560
561         # There is SIP user for the called address. Before trying PSTN,
562         # you may have to convert the adress, for instance by using
563         # ENUM.
564         #route(ENUM);
565
566         # Last resort: if none of the previous route has found
567         # the recepient, try PSTN.
568         route(PSTN);
569
570         # nothing matched
571         sl_reply("404", "No route matched");
572 }
573
574 # Forward a request to the destination set.
575 #
576 route[FORWARD]
577 {
578         # If this is called from the failure route we need to add a new
579         # branch.
580         if (isflagset(FLAG_FAILUREROUTE)) {
581                 if (!append_branch()) {
582                         t_reply("500", "Too many branches");
583                         drop;
584                 }
585         }
586
587         # If this is an initial INVITE (without a To-tag) we might try
588         # another target (call forwarding or voicemail) after receiving
589         # an error.
590         if (method=="INVITE" && !@to.tag) {
591                 t_on_failure("FAILURE_ROUTE");
592         }
593
594         # Always use the reply route to check for NATed UAS.
595         t_on_reply("REPLY_ROUTE");
596
597         # Insert a Record-Route header into all requests.
598         # This has to be done as one of the last steps to include all the
599         # RR cookies which might have been created during the script run.
600         route(RR);
601
602         # Activate the RTP proxy as the last step because it modifies the
603         # body.
604         route(RTPPROXY);
605
606         # Remove credentials to keep requests shorter
607         if (isflagset(FLAG_AUTH_OK) && !isflagset(FLAG_DONT_RM_CRED) ) {
608                 consume_credentials();
609         }
610
611         # Send it out now.
612         if (!t_relay()) {
613                 if (isflagset(FLAG_FAILUREROUTE)) {
614                         # XXX This should be replaced with
615                         #     t_reply_error() similar to sl_reply_error()
616                         #     in order to return the proper failure code.
617                         #     Only, there is no such function yet.
618                         t_reply("500", "Request cannot be forwarded");
619                 }
620                 else {
621                         sl_reply_error();
622                 }
623         }
624         drop;
625 }
626
627
628 # Perform initial checks on an incoming request.
629 #
630 # Rejects the request if it fails any of the checks.
631 #
632 route[INIT]
633 {
634         # Messages with a Max-Forwards header of zero.
635         if (!mf_process_maxfwd_header("10")) {
636                 sl_reply("483","Too Many Hops");
637                 drop;
638         }
639
640         # Set flag for use in the onsend route
641         if (@to.tag) {
642                 setflag(FLAG_TOTAG);
643         }
644
645         # Check if the UAC is NATed and fix the message accordingly
646         route(NAT_DETECTION);
647
648         # Activate accounting for all initial INVITEs. In-dialog requests
649         # are accounted by a RR cookie (see below).
650         if (method == "INVITE" && !@to.tag) {
651                 setflag(FLAG_ACC);
652         }
653
654         # Set flag and use it instead of the attribute.
655         if ($replicate==1) {
656                 setflag(FLAG_REPL_ENABLED);
657         }
658 }
659
660
661 # Reply OPTIONS requests sent to the proxy itself.
662 #
663 route[OPTIONS_REPLY]
664 {
665         # OPTIONS requests without a username in the Request-URI but one
666         # of our domains or IPs are addressed to the proxy itself and
667         # can be answered statelessly.
668         if (method == "OPTIONS" && !@ruri.user && (uri == myself || $t.did))
669         {
670                 options_reply();
671                 drop;
672         }
673 }
674
675
676 # Check if the sender of the request is behind a NAT device. If so,
677 # fix the request so that other devices can talk to the sender nonetheless.
678 #
679 route[NAT_DETECTION]
680 {
681         # Lots of UAs do not include the rport parameter in there Via
682         # header, so we put it there regardless.
683         force_rport();
684         force_tcp_alias();
685
686         # Check if the request contains hints for a NATed UAC. Also, try to
687         # rewrite contacts using maddr. Using maddr is a really dubious
688         # technique and we better replace such with transport address.
689         # Downside: it fails for clients fronted by another server, in
690         # which case a valid contact we dislike because of maddr will be
691         # substituted inapproprietely (e.g., WM from other domains will
692         # fail). If you are worried about that, remove tests for maddr and
693         # recompile SER using HONOR_MADDR.  Also note that rewriting
694         # contacts may possibly lead to client denying subseqent requests
695         # to them because they don't recognized fixed contacts as their
696         # own.  Should you encounter such a case, a possible solution
697         # would be to store the original information as a contact parameter
698         # and restore it on its way back.
699         if (nat_uac_test("19")
700             || (@hf_value["contact"] && @contact.uri.params.maddr))
701         {
702                 setflag(FLAG_NAT);
703                 $uac_nat = 1;
704                 setavpflag($uac_nat, "dialog_cookie");
705                 if (method == "REGISTER") {
706                         # Prepare the Contact so that the registrar module
707                         # saves the source address and port as well.
708                         fix_nated_register();
709                 }
710                 else {
711                         # Overwrite the Contact to allow proper in-dialog
712                         # routing.
713                         fix_nated_contact();
714                 }
715         }
716 }
717
718
719 # Activates RTP proxy if necessary.
720 #
721 route[RTPPROXY]
722 {
723         # If no NAT is involved we dont have to do here anything.
724         if (!isflagset(FLAG_NAT)) {
725                 break;
726         }
727
728         # If the message terminates a dialog turn RTP proxy off.
729         if (method == "BYE" || method == "CANCEL") {
730                 unforce_rtp_proxy();
731                 append_hf("P-RTP-Proxy: UNFORCED\r\n");
732                 break;
733         }
734
735         # Turn the RTP proxy on for INVITEs and UPDATEs.
736         if (((method=="INVITE" || method == "UPDATE") && @msg.body)
737             && !isflagset(FLAG_RTP_PROXY))
738         {
739                 force_rtp_proxy('r');
740                 append_hf("P-RTP-Proxy: YES\r\n");
741                 setflag(FLAG_RTP_PROXY);
742         }
743 }
744
745
746 # Handling of loose routed requests
747 #
748 #    XXX Isn't the proper term "record routed"? This route also handles
749 #        strict routed requests, doesn't it? -- martinh
750 route[LOOSE_ROUTE]
751 {
752         # subsequent messages withing a dialog should take the
753         # path determined by the Route headers.
754         if (loose_route()) {
755                 # Mark routing logic in request.
756                 append_hf("P-hint: rr-enforced\r\n");
757
758                 # If the Route contained the accounting AVP cookie we
759                 # set the accounting flag for the acc_db module.
760                 # This is more for demonstration purpose as this could
761                 # also be solved without RR cookies.
762                 # Note: this means all in-dialog request will show up in
763                 # the accounting tables, so prepare your accounting software
764                 # for this.
765                 if ($account == "yes") {
766                         setflag(FLAG_ACC);
767                 }
768
769                 # Restore the NAT flag if present
770                 if ($uac_nat == 1) {
771                         setflag(FLAG_NAT);
772                 }
773
774                 # Restore Session Timer flag and headers.
775                 if ($stimer && ($stimer != "0")) {
776                         route(SESSION_TIMER);
777                 }
778
779                 # Some broken devices overide the dialog route set with the
780                 # Record-Route headers from each in-dialog request. So, we
781                 # better add Record-Route headers again. If we call
782                 # record_route() after loose_route(), the AVP cookies are
783                 # restored automatically. Additionally, there is a scenario
784                 # where Record-Route headers are necessary if an initial
785                 # SUBSCRIBE is forked.
786                 #
787                 # Note that here we forward before authentication checks
788                 # are executed. Generally, we only authenticate
789                 # out-of-dialog requests. Some in-dialog requests can't be
790                 # authenticated at all, see the call-forwarding example in
791                 # route[DOMAIN].
792                 route(RR);
793
794                 route(FORWARD);
795         }
796 }
797
798
799 # Add a Record-Route header
800 #
801 route[RR]
802 {
803         if (!isflagset(FLAG_RR_DONE) && method != "REGISTER") {
804                 # We record-route all messages to make sure that
805                 # subsequent messages will go through our proxy. This is
806                 # particularly good if upstream and downstream entities
807                 # use different transport protocols.
808
809                 # If the ACC flag is set, store this in a Record-Route
810                 # AVP cookie. This is more for demonstration purposes.
811                 if (isflagset(FLAG_ACC)) {
812                         $account = "yes";
813                         setavpflag($account, "dialog_cookie");
814                 }
815
816                 # Insert the RR header.
817                 record_route();
818
819                 # This flag allows to call this route several times
820                 # without inserting several RR headers.
821                 setflag(FLAG_RR_DONE);
822         }
823 }
824
825
826 # Look up the domains of the caller and the callee.
827 #
828 route[DOMAIN]
829 {
830         # Check whether the caller is from a local domain.
831         lookup_domain("$fd", "@from.uri.host");
832
833         # Check whether the callee is at a local domain
834         lookup_domain("$td", "@ruri.host");
835 }
836
837
838 # Check domain usage policies and reject illegal requests.
839 #
840 route[DOMAIN_POLICY]
841 {
842
843         # If we don't know the domain of the caller nor the domain of the
844         # callee, somone tries to use our proxy as a relay.  However, we
845         # can only apply this check out-of-dialog requests without a To
846         # tag.  In some cases such as call-forwarding, subsequent requests
847         # may not include served domain neither as origination nor
848         # destination (a@A calls b@B who forwards to c@C. A BYE by c@C is
849         # then From b@B and To a@A. There is no mentioning of c@C despite
850         # legitimate behaviour of c@C).
851         if (!isflagset(FLAG_TOTAG) && !$t.did && !$f.did) {
852                 sl_reply("403", "Relaying Forbidden");
853                 drop;
854         }
855 }
856
857
858 # The Registrar
859 #
860 route[REGISTRAR]
861 {
862         # Process only REGISTERs here.
863         if (method != "REGISTER") {
864                 break;
865         }
866
867         # If this is a replica (sent to the multicast address), trust it to
868         # be secure and store it in usrloc
869         if (dst_ip==224.0.1.75) {
870                 if (!isflagset(FLAG_REPL_ENABLED)) {
871                         # Multicast replication administratively disabled.
872                         # Ignore.
873                         drop;
874                 }
875
876                 # Read marker from master
877                 if (search("^Repl-Marker: nated")) {
878                         setflag(FLAG_NAT);
879                         $uac_nat = 1;
880                 }
881
882                 # If the replicating server added its own server id to the
883                 # request, obtain the value and store it in an attribute.
884                 # This is used by registrar.
885                 $server_id = @msg.header["SER-Server-ID"];
886
887                 # Assume URI in form of UID@mydomain and store contacts
888                 # under this UID.  Note that this only works if local policy
889                 # causes UIDs to have form compliant to RFC3261 URI
890                 # usernames.
891                 $tu.uid = @ruri.user;
892                 if (!save_mem_nr("location")) {
893                         log(1, "Error while saving replicated REGISTER.\n");
894                 }
895                 drop;
896         }
897         else {
898                 # This is a REGISTER request received from the UA. Remove
899                 # our internal header fields if they are present. The may
900                 # have been added maliciously.
901                 remove_hf("SER-Server-ID");
902                 remove_hf("Repl-Marker");
903         }
904
905         # Check if the REGISTER if for one of our local domains.
906         if (!$t.did) {
907                 sl_reply("403", "Register Forwarding Forbidden");
908                 drop;
909         }
910
911         # The REGISTER target is in the To header, so reload the domain.
912         if (!lookup_domain("$td", "@to.uri.host")) {
913                 sl_reply("404", "Unknown Domain");
914                 drop;
915         }
916
917         # Useful for clients that ignore expires in 200 (OK). This is an
918         # attempt to keep them sticking to our value of 600.
919         append_to_reply("Expires: 600\r\n");
920         append_to_reply("Min-Expires: 240\r\n");
921
922         # We want only authenticated users to be registered.
923         if (!www_authenticate("$fd.digest_realm", "credentials")) {
924                 if ($? == -2) {
925                         sl_reply("500", "Internal Server Error");
926                 }
927                 else if ($? == -3) {
928                         sl_reply("400", "Bad Request");
929                 }
930                 else {
931                         if ($digest_challenge) {
932                                 append_to_reply("%$digest_challenge");
933                         }
934                         sl_reply("401", "Unauthorized");
935                 }
936                 drop;
937         }
938
939         # Check if the authenticated user is the same as the target user.
940         if (!lookup_user("$tu.uid", "@to.uri")) {
941                 sl_reply("404", "Unknown user in To");
942                 drop;
943         }
944
945         # the authentication ID does not match the ID in the To header
946         if ($f.uid != $t.uid) {
947                 sl_reply("403", "Authentication and To-Header mismatch");
948                 drop;
949         }
950
951         # Check if the authenticated user is the same as the request
952         # originator. You may uncomment it if you care, which URI is in
953         # the From header.
954         #if (!lookup_user("$fr.uid", "@from.uri")) {
955         #       sl_reply("404", "Unknown user in From");
956         #       drop;
957         #}
958         #if ($fu.uid != $fr.uid) {
959         #       sl_reply("403", "Authentication and From-Header mismatch");
960         #       drop;
961         #}
962
963         # Everything is fine. Store the binding.
964         if (!save_contacts("location")) {
965                 sl_reply("400", "Invalid REGISTER Request");
966                 drop;
967         }
968         if (isflagset(FLAG_REPL_ENABLED)) {
969                 if (isflagset(FLAG_NAT)) {
970                         append_hf("Repl-Marker: nated\r\n");
971                 }
972                 # Append this server's unique ID to the request
973                 append_hf_value("SER-Server-ID", "%@sys.server_id");
974                 # We are multicasting a successful REGISTER to all proxies
975                 # on the multicast network to replicate the contact
976                 # addresses to all of them. In case they share the same IP
977                 # address (VIP) it is important to set the sending IP
978                 # address to an unshared one (in the future a special mcast
979                 # module may use unbound sockets for sending and leave
980                 # the source IP address decision up to kernel routing
981                 # tables).
982                 #DEBCONF-REPL_SEND_ADDR-START
983                 force_send_socket(udp:127.0.0.1);
984                 #DEBCONF-REPL_SEND_ADDR-END
985                 # Put the UID in the Request-URI so that it doesn't have to
986                 # be looked up in the database by all multicast receivers.
987                 attr2uri("$tu.uid","user");
988                 forward_udp(224.0.1.75,5060);
989         }
990         drop;
991 }
992
993
994 # Authentication of request originators claiming to belong to one of our
995 # domains.
996 #
997 route[AUTHENTICATION]
998 {
999         # CANCELs and ACKs cannot be challenged.
1000         if (method=="CANCEL" || method=="ACK") {
1001                 break;
1002         }
1003
1004         # Requests from non-local to local domains should be permitted.
1005         # Remove this if you want a walled garden.
1006         if (!$f.did) {
1007                 break;
1008         }
1009
1010         # Gateways are usually not able to authenticate for their requests.
1011         # You have to trust them base on some other information such as the
1012         # source IP address.
1013         # WARNING: If at all this is only safe in a local network!
1014         if (@src.ip == $gw_ip) {
1015                 break;
1016         }
1017
1018         if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
1019                 if ($? == -2) {
1020                         sl_reply("500", "Internal Server Error");
1021                 }
1022                 else if ($? == -3) {
1023                         sl_reply("400", "Bad Request");
1024                 }
1025                 else {
1026                         if ($digest_challenge) {
1027                                 append_to_reply("%$digest_challenge");
1028                         }
1029                         sl_reply("407", "Proxy Authentication Required");
1030                 }
1031                 drop;
1032         }
1033
1034         # Check if the UID derived from authentication matches that from
1035         # the From header.
1036         if (!lookup_user("$fr.uid", "@from.uri")) {
1037                 sl_reply("403", "Fake Identity");
1038                 drop;
1039         }
1040         if ($fu.uid != $fr.uid) {
1041                 sl_reply("403", "Fake Identity");
1042                 drop;
1043         }
1044         setflag(FLAG_AUTH_OK);
1045
1046         # Load the user attributes of the caller.
1047         load_attrs("$fu", "$f.uid");
1048 }
1049
1050
1051 # Process request targeted to non-local domains.
1052 #
1053 route[OUTBOUND]
1054 {
1055         # If a local user calls to a foreign domain we play outbound
1056         # proxy for them.
1057         # Comment this out if you want a walled garden.
1058         if ($f.did && !$t.did) {
1059                 append_hf("P-hint: outbound\r\n");
1060                 route(FORWARD);
1061         }
1062 }
1063
1064
1065 # Process speeddial addresses.
1066 #
1067 route[SPEEDDIAL]
1068 {
1069         # If the caller is local and uses two digits only, we redirect the
1070         # UA to the real target.
1071         if ($fd.did && uri =~ "sip:[0-9][0-9]@") {
1072                 if (sd_lookup("speed_dial")) {
1073                         sl_reply("302", "Speed Dial Redirect");
1074                 }
1075                 else {
1076                         sl_reply("404", "Speed Dial Not Found");
1077                 }
1078                 drop;
1079         }
1080 }
1081
1082
1083 # Process requests targeted to a local user.
1084 #
1085 route[INBOUND]
1086 {
1087         # lets see if know the callee
1088         if (!lookup_user("$tu.uid", "@ruri")) {
1089                 break;
1090         }
1091
1092         # Load the attributes of the callee.
1093         load_attrs("$tu", "$t.uid");
1094
1095         # You can check if the called URI is in fact an alias like this.
1096         #if (! $tu.uri_canonical) {
1097         #       # If the alias URI has different attributes, you can load
1098         #       # them into the URI track like this.
1099         #       load_attrs("$tr", "@ruri");
1100         #}
1101
1102         # Check for call forwarding of the callee.
1103         # Note: The forwarding target has to be full routable URI
1104         #       in this example.
1105         if ($tu.fwd_always_target) {
1106                 attr2uri("$tu.fwd_always_target");
1107
1108                 # If we are forwarding to ourselves, don't remove
1109                 # credentials. Otherwise the request would be challenged
1110                 # again.
1111                 # Note: This doesn't apply to failure_route which may
1112                 # still be problematic -- credentials are already
1113                 # removed when we forward. Consider using a 3xx.
1114                 lookup_domain("$td", "@ruri.host");
1115                 if ($t.did) {
1116                         setflag(FLAG_DONT_RM_CRED);
1117                 }
1118                 route(FORWARD);
1119         }
1120
1121         # Native SIP destinations are handled using the usrloc database.
1122         if (lookup_contacts("location")) {
1123                 append_hf("P-hint: usrloc applied\r\n");
1124
1125                 # We set the tm module timers according to the prefences
1126                 # of the callee (avoid too long ringing of his phones).
1127                 # Note1: Timer values have to be in ms now!
1128                 # Note2: This makes even more sense if you switch to a
1129                 #        voicemail from the FAILURE_ROUTE below.
1130                 if ($t.fr_inv_timer) {
1131                         if ($t.fr_timer) {
1132                                 t_set_fr("$t.fr_inv_timer", "$t.fr_timer");
1133                         }
1134                         else {
1135                                 t_set_fr("$t.fr_inv_timer");
1136                         }
1137                 }
1138
1139                 # This enables session timer support as long as one side
1140                 # supports it.  If you want to have session timmer support
1141                 # only for calls from your PSTN gateway but not between pure
1142                 # VoIP calls you can remove the comment marks from the if
1143                 # clause in the next line and closing bracket below.
1144                 # WARNING: If at all you should trust IP addresses only in
1145                 #          your local network!
1146                 #if (@src.ip == $gw_ip) {
1147                         route(SESSION_TIMER);
1148                 #}
1149
1150                 route(FORWARD);
1151         }
1152         else {
1153                 sl_reply("480", "Temporarily unavailable");
1154                 drop;
1155         }
1156 }
1157
1158
1159 # Process calls for PSTN.
1160 #
1161 route[PSTN]
1162 {
1163         # Check some conditions first:
1164         # PSTN is available for our own users only.
1165         if (!$f.did) {
1166                 break;
1167         }
1168
1169         # If the attribute $gw_ip isn't set, there is no PSTN service
1170         # active.
1171         if (!$gw_ip) {
1172                 break;
1173         }
1174
1175         # And finally, the username of the Request-URI must look like
1176         # a phone number.
1177         if (!uri =~ "^sips?:\+?[0-9]{3,18}@") {
1178                 break;
1179         }
1180
1181         # You may have to convert the number in the Request-URI into a
1182         # format that is accepted by your gateway here.
1183
1184         # Check permissions of the caller for initial INVITEs.
1185         if (method == "INVITE" && !@to.tag) {
1186                 if (!$f.gw_acl == "1") {
1187                         sl_reply("403", "PSTN Not Permitted");
1188                         drop;
1189                 }
1190         }
1191
1192         # If the attribute $asserted_id is set, we add its contents as a
1193         # Remote-Party-ID header.
1194         # Depending on your gateway, you may have to add a
1195         # P-Asserted-Identity header here instead.
1196         if ($asserted_id) {
1197                 xlset_attr("$rpidheader",
1198                         "<sip:%$asserted_id@%@ruri.host>;screen=yes");
1199                 replace_attr_hf("Remote-Party-ID", "$rpidheader");
1200         }
1201
1202         # Enable Session Timer support with the gateway.
1203         route(SESSION_TIMER);
1204
1205         # Replace the domain part of the Request-URI with the value from
1206         # the attribute  and send it out.
1207         attr2uri("$gw_ip", "domain");
1208
1209         # Set the PSTN_ALLOWED flag. This will be checked on the
1210         # onsend_route.
1211         setflag(FLAG_PSTN_ALLOWED);
1212         route(FORWARD);
1213 }
1214
1215
1216 # Try to process CANCEL requests quickly.
1217 #
1218 route[CATCH_CANCEL]
1219 {
1220         if (method == CANCEL) {
1221                 # t_relay_cancel() will stop processing if a matching
1222                 # INVITE was found.
1223                 if (!t_relay_cancel()) {
1224                         # An INVITE was found but some error occurred.
1225                         sl_reply("500", "Internal Server Error");
1226                         drop;
1227                 }
1228                 # Bad luck, no corresponding INVITE was found, we have to
1229                 # continue with the script.
1230         }
1231 }
1232
1233
1234 # Site specific policy.
1235 #
1236 route[SITE_SPECIFIC]
1237 {
1238         # This is only relevant for requests for one of our domains.
1239         if (!$t.did) {
1240                 break;
1241         }
1242
1243         # Do site specific routing such as peering.
1244         # For example:
1245         if (uri=~"^sip:000777") {
1246                 rewritehostport("sems01.iptel.org:5074");
1247                 route(FORWARD);
1248         }
1249 }
1250
1251 # Process Session-Timer.
1252 #
1253 route[SESSION_TIMER]
1254 {
1255         # We are only interested in session establishment or session
1256         # refreshing.
1257         #
1258         if (method != "INVITE" && method != "UPDATE") {
1259                 break;
1260         }
1261
1262         # Let's check if the Session-Expires header is already present.
1263         if (@hf_value.session_expires) {
1264                 # Compare the Session-Expires header value with the
1265                 # configured Min-SE.
1266                 eval_push("x:%@hf_value.session_expires.uri");
1267                 eval_oper("(int)", -1);
1268                 eval_push("x:%@cfg_get.session_timer.min_se");
1269                 eval_oper("(int)", -1);
1270                 eval_oper(">=", -2);
1271
1272                 # Let's check for the Suported header.
1273                 if (hf_value_exists("Supported", "timer")) {
1274                         # The UAC supports Session-Timer, so we
1275                         # only need to take a look at the values
1276                         if (@eval.pop[-1] == "0") {
1277                                 # Session interval is lower than the
1278                                 # configured Min-SE
1279                                 append_to_reply("Min-SE: %@cfg_get.session_timer.min_se\r\n");
1280                                 sl_reply("422", "Session Interval Too Small");
1281                                 drop;
1282                         }
1283
1284                         # We store the session expires value for the reply
1285                         # route and mark the attribute for inserting as
1286                         # Record-Route cookie.
1287                         $stimer = @hf_value.session_expires.uri;
1288                         setavpflag($stimer, "dialog_cookie");
1289
1290                         # Set the session timer flag that indicates the
1291                         # UAC supports the extension.
1292                         setflag(FLAG_SESSIONTIMER);
1293                 }
1294                 else {
1295                         # Session epxires was already inserted by some other
1296                         # proxy
1297                         if (@eval.pop[-1] == "0") {
1298                                 # Session interval is lower than the
1299                                 # configured Min-SE. There is no point in
1300                                 # sending 422 response, because the UAC
1301                                 # does not support the extension, the values
1302                                 # can be corrected instead.
1303                                 assign_hf_value("Session-Expires",
1304                                         "%@cfg_get.session_timer.min_se");
1305                                 remove_hf_value("Min-SE");
1306                                 append_hf_value("Min-SE",
1307                                         "%@cfg_get.session_timer.min_se");
1308                         }
1309                 }
1310         }
1311         else {
1312                 # No Session Timer is requested yet, neither by UAC nor by
1313                 # proxy
1314                 if (@cfg_get.session_timer.default != "0") {
1315                         # Add a Session Expires header to see if the UAS
1316                         # supports Session Timer. We do not insert a
1317                         # Required header because then the call might fail.
1318                         append_hf_value("Session-Expires",
1319                                 "%@cfg_get.session_timer.default");
1320                         if (@cfg_get.session_timer.min_se != "90") {
1321                                 append_hf_value("Min-SE",
1322                                         "%@cfg_get.session_timer.min_se");
1323                         }
1324
1325                         # Mark the attribute to be inserted as a
1326                         # Record-Route cookie
1327                         $stimer = @cfg_get.session_timer.default;
1328                         setavpflag($stimer, "dialog_cookie");
1329                 }
1330         }
1331 }
1332
1333
1334 # Failure route for initial INVITEs.
1335 #
1336 failure_route[FAILURE_ROUTE]
1337 {
1338         # Mark that we are operating from a failure route.
1339         setflag(FLAG_FAILUREROUTE);
1340
1341         if (t_check_status("486|600")) {
1342                 # If we received a busy and a busy target is set, forward
1343                 # it there.
1344                 # Note: Again, the forwarding target has to be a routeable
1345                 # URI. We redirect using 3xx to avoid possible issues with
1346                 # credentials (if we consumed them, they may be missing in
1347                 # a loop, if we don't consume them, messages are bigger and
1348                 # more vulnerable)
1349                 if ($tu.fwd_busy_target) {
1350                         #attr2uri("$tu.fwd_busy_target");
1351                         #route(FORWARD);
1352                         attr_destination("$tu.fwd_busy_target");
1353                         t_reply("302", "Redirect On Busy");
1354                 }
1355                 # Alternatively, you could forward the request to
1356                 # SEMS/voicemail here
1357         }
1358         else if (t_check_status("408|480")) {
1359                 # If we received no answer and the noanswer target is set,
1360                 # forward it there.
1361                 # Note: See above.
1362                 if ($tu.fwd_noanswer_target) {
1363                         #attr2uri("$tu.fwd_noanswer_target");
1364                         #route(FORWARD);
1365                         attr_destination("$tu.fwd_noanswer_target");
1366                         t_reply("302", "Redirect On No Answer");
1367                 }
1368         }
1369 }
1370
1371
1372 # Onreply route that fixes NAT in responses.
1373 #
1374 onreply_route[REPLY_ROUTE]
1375 {
1376         # Fix the Contact in the reply if it contains a private IP to
1377         # allow proper routing of in-dialog messages.
1378         # Do the same if the contact is maddred. See the notes in route
1379         # [NAT_DETECTION] for more information.
1380         if (nat_uac_test("1") ||
1381             (@hf_value["contact"] && @contact.uri.params.maddr))
1382         {
1383                 fix_nated_contact();
1384         }
1385
1386         # If RTP proxy was activated and this is a 18x or 2xx reply with a
1387         # body, inform RTP proxy.
1388         if (isflagset(FLAG_RTP_PROXY)
1389             && status=~"(18[03])|(2[0-9][0-9])"
1390             && @msg.body)
1391         {
1392                 force_rtp_proxy('r');
1393         }
1394
1395         # Let's check for session timer support.
1396         if (isflagset(FLAG_SESSIONTIMER) && status =~ "2[0-9][0-9]") {
1397                 # The UAC wanted to have a session timer.
1398                 if (!@hf_value.session_expires) {
1399                         # But the UAS does not support it, so we will try
1400                         # to convince the UAC to do it.
1401                         append_hf_value("Session-Expires",
1402                                 "%$stimer;refresher=uac");
1403                         if (!hf_value_exists("Require", "timer")) {
1404                                 include_hf_value("Require", "timer");
1405                         }
1406                 }
1407         }
1408 }
1409
1410
1411 # Do some final checks before a request is sent out.
1412 onsend_route
1413 {
1414         # Bypass check: Eliminate requests to the PSTN gateway if they have
1415         # not passed ACL checks and are not marked with FLAG_PSTN_ALLOWED
1416         # but are dialog-initiating requests (no to-tag, no CANCEL, no ACK).
1417         # This helps to stop policy bypasses (gateway IP uploaded as a
1418         # forked contact, or a call-forwarding destination, or a DNS name,
1419         # or a preloaded route, or something else possibly)
1420         if (to_ip==$g.gw_ip && !isflagset(FLAG_PSTN_ALLOWED)
1421             && !isflagset(FLAG_TOTAG)
1422             && method != "ACK" && method != "CANCEL")
1423         {
1424                 log(1, "ALERT: non authorized packet for PSTN, dropping...\n%mb\n");
1425
1426                 # You can't use advanced features from onsend_route.
1427                 # xlog("L_ALERT", "non authorized packet for PSTN, dropping...\n%mb\n");
1428                 drop;
1429         }
1430
1431         # RFC 1918 relay protection: Useful if SER is attached to an
1432         # administrative network using private IP address space and you
1433         # wish to prevent UACs from relaying their packets there.
1434         #
1435         # You will have to comment this out, if you are regularly serving
1436         # an RFC 1918 address space.
1437         if (to_ip==10.0.0.0/8 || to_ip==172.16.0.0/12
1438             || to_ip==192.168.0.0/16)
1439         {
1440                 log(1, "ALERT: Packet targeted to an RFC1918 address dropped\n");
1441                 drop;
1442         }
1443 }
1444
1445
1446 # Run every minute by the timer module.
1447 #
1448 route[ON_1MIN_TIMER] {
1449         # Cleanup expired location records
1450         # MySQL version:
1451         db_query("delete from location where expires<utc_timestamp()");
1452         # PostgreSQL version:
1453         #db_query("delete from location where expires<now()");
1454
1455
1456         # Reload domains if domain table has been changed recently.
1457         # Note: because global attributes are read-only and we can't
1458         # easily remember the "last" status, we check for changed
1459         # timestamp in 2 minute time-interval.
1460         # MySQL version:
1461         db_query("select value from global_attrs where name='domain_data_version' and type=0 and cast(value as unsigned int) between unix_timestamp(now())-120 and unix_timestamp(now())", "reload");
1462         # PostgreSQL version:
1463         #db_query("select value from global_attrs where name='domain_data_version' and type=0 and cast(value as integer) between date_part('epoch', now() - interval '120 seconds') and date_part('epoch', now())", "reload");
1464         if (@db.fetch.reload.count=="1") {
1465                 # Domain reload only available as fifo command.
1466                 exec_msg("sercmd domain.reload");
1467         }
1468         db_close("reload");
1469 }
1470