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