5 # Applicability of this Configuration File
6 # ----------------------------------------
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
18 # If you look for a simpler version with a lot less dependencies
19 # please refer to the sip-router-basic.cfg file in your SER distribution.
21 # If you look for documentation, try http://sip-router.org/wiki/.
22 # The right mailing lists for questions about this file is
23 # <sr-users@lists.sip-router.org>.
27 # running DB, running RTP proxy, one public IP address
28 # for SIP service, one private IP address for administrative purposes;
29 # optional: IP address of a PSTN gateway
33 # To get this config running you need to execute the following commands
34 # with the new serctl (the capital word are just place holders):
36 # $ ser_ctl domain add DOMAINNAME
37 # $ ser_ctl user add USERNAME@DOMAINNAME -p PASSWORD
39 # (ser_ctl can be obtained from
40 # http://ftp.iptel.org/pub/serctl/daily-snapshots/ )
42 # If you want to have P-Asserted-ID header for your user
44 # $ ser_attr add uid=UID asserted_id="PID"
46 # If you want to have (PSTN) gateway support:
48 # $ ser_db add attr_types name=gw_ip rich_type=string raw_type=2 \
49 # description="The gateway IP for the default ser.cfg" default_flags=33
50 # $ ser_attr add global gw_ip=GATEWAY-IP
52 # Alternatively, you can simple uncomment the relevant line in this file
53 # right at the beginning of the main route.
55 # You can also use serweb to set all the values above
56 # (http://ftp.iptel.org/pub/serweb/daily-snapshots/ or
57 # http://developer.berlios.de/projects/serweb).
59 # Users with permission to call PSTN using this script must have
60 # the $gw_acl attribute set properly, and shall have $asserted_id
61 # set to indicate their caller-id for calls to PSTN. For inbound
62 # calls from PSTN, additional aliases may be also set.
66 # If this file is installed on Debian from package 'ser-oob' then some
67 # options in this configuration file may be set by post-installation
68 # script, according to values entered by user at installation time in
69 # debconf configuration. These values are then applied automatically to
70 # this file each time the 'ser-oob' package is upgraded or reconfigured by
71 # calling 'dpkg-reconfigure sip-router-oob'.
73 # The parts of this configuration file that may be altered by debconf are
74 # enclosed between '#DEBCONF-something-START' and '#DEBCONF-something-END'
75 # comment marks. Please do not remove them.
78 # TODO (Future possible improvements):
79 # ---------------------------------------
81 # - AVP-based diversion for call-forwarding (as opposed to specialized
83 # - add Date header in 200s to REGISTERs (to be packaged with NTP!)
89 # - Re-name all internal headers so that they start with a common prefix,
90 # such as P-SER and then wipe all such headers from requests received
91 # from untrusted sources, such as the user agents or foreign proxy
93 # * refined DB use (e.g., flatstore for acc)
95 # - dialog module for monitoring purposes
96 # - more extensive logging using xlog (controlled by gflags/gAVPs)
97 # * leveraging 2.1 features:
98 # - removal of private IP address (it takes a multicast-specific
99 # command which will allow OS to determine source IP address)
101 # * don't use exec (it takes domain.reload as script command)
102 # * compare last-stored timestamp with current timestamp (it takes
103 # assignment of gAVPs)
104 # * check multicast REGISTERs for their TTL (this is a simple and
105 # effective security check to prevent remote multicast messages
106 # to damage our traffic)
107 # - numerous fine-tuning parameters which are only available in 2.1
108 # (mlock_pages, dns_try_naptr, etc.)
109 # - better support for preloaded routes with domain name
111 # Security considerations:
112 # ------------------------
113 # The script has been tested against security leaks, but it comes
114 # under terms of GPL "as is" without any warranties; better check
116 # - IP based authentication of PSTN gateway and multicast REGISTERs
117 # is compliant to your network setup and security policy.
118 # - Multiple gateway IPs can't be provisioned as security checks
119 # are applied only to one.
123 # Copyright (C) 2005-2008 iptelorg GmbH
124 # This file is part of SER, a free SIP server. It is available under the
125 # terms of the GNU General Public License.
126 # Numerous folks have contributed to this file, including but not limited
127 # to Andrei, Jan, Jiri, Michal, Miklos, Nils.
130 # .... that's it, enough of yadiyada, here the real config begins!
132 # ----------- Global Defines / Extra Features -------------------------------
133 # (can be enabled either by uncommenting the corresponding #!define
134 # statement or by starting with -A WITH_<FEATURE_NAME>, e.g.
135 # ser -A WITH_TLS -f /etc/ser/ser-oob.cfg )
140 #enable xmlrpc support
141 ##!define WITH_XMLRPC
143 # xmlrpc allowed only if it comes on TLS from a client with a valid cert
144 ##!define XMLRPC_TLS_ONLY
146 # xmlrpc allowed subnets (if defined XMLRPC requests with source ip matching
147 # this network addresses will be allowed, if no XMLRPC_ALLOWED_SUBNETx is
148 # defined only requests coming from localhost will be allowed).
149 # E.g.: ser -A XMLRPC_ALLOW_NET1=192.168.1.0/24 -f ser-oob.cfg
150 ##!define XMLRPC_ALLOW_NET1 192.168.0.0/16
151 ##!define XMLRPC_ALLOW_NET2 10.0.0.0/255.0.0.0
152 ##!define XMLRPC_ALLOW_NET3 172.16.0.0/12
155 # started from compile directory (not installed)
156 ##!define LOCAL_TEST_RUN
158 # ----------- Global Configuration Parameters -------------------------------
160 #debug=3 # debug level (cmd line: -ddd)
161 #memdbg=10 # memory debug log level
162 #memlog=10 # memory statistics log level
163 #log_facility=LOG_LOCAL0 # the facility used for logging (see syslog(3))
165 #DEBCONF-SERVERID-START
167 #DEBCONF-SERVERID-END
169 # Uncomment these lines to enter debugging mode or start SER with
175 check_via=no # (cmd. line: -v)
176 dns=no # (cmd. line: -r)
177 rev_dns=no # (cmd. line: -R)
182 #disable_core=yes # disables core dumping
183 #open_files_limit=20480 # sets the open file descriptors limit
184 #mhomed=yes # usefull for multihomed hosts, small performance
186 disable_tcp=no # be conservative about enabling TCP -- it can
187 # degrade performance a lot
188 #tcp_accept_aliases=yes # accepts the tcp alias via option
189 phone2tel=no # ignore user=phone in request-URIs -- otherwise
190 # these URIs would be interpreted as equivalent
191 # to TEL URIs, and their lookup would fail in URI
196 #DEBCONF-LISTEN-START
199 # sip.mcast.net for REGISTER replication
200 #DEBCONF-LISTEN_REPL-START
201 listen=udp:224.0.1.75
202 #DEBCONF-LISTEN_REPL-END
203 # administrative interface -- needed for example for multicast source
205 #DEBCONF-LISTEN_ADMIN-START
207 #DEBCONF-LISTEN_ADMIN-END
209 #listen=tls:127.0.0.1:5061
215 # ------------------- DNS Parameters ----------------------------------------
216 # (see doc/dns.txt for more details)
222 dns_use_search_list=no
224 # dns cache & failover
228 dns_cache_negative_ttl=300
230 dns_cache_max_ttl=86400 # 1 day
231 dns_cache_mem=2048 # 2 MB
232 dns_cache_gc_interval=60 # garbage collection every minute
233 # ser 2.1 specific options
235 dns_srv_lb=yes # srv based load balancing
236 dns_udp_pref=3 # prefer udp (when resolving naptr record)
237 dns_tcp_pref=2 # if no udp available accept tcp (for naptr)
238 dns_sctp_pref=2 # same preference as tcp
240 dns_tls_pref=1 # low preference (heavy resource use)
242 dns_tls_pref=-1 # ignore / don't accept tls (for naptr)
244 # dns_cache_delete_nonexpired=no
246 # ------------------- Blacklist Parameters ----------------------------------
247 # (see doc/dst_blacklist.txt for more details)
250 dst_blacklist_mem=1024 # 1 MB
251 dst_blacklist_expire=300 # blacklist default time
252 dst_blacklist_gc_interval=150 # 2.5 min
253 # for sip-router 2.1 to the above add tm blst_503* parameters and/or use the
254 # blst module (see NEWS)
256 # ------------------- TCP Parameters ----------------------------------------
257 # (see NEWS for more details)
258 tcp_connection_lifetime=3600
259 #tcp_max_connections=10240 # default is 2048
260 tcp_connect_timeout=1
263 # ------------------- TLS Parameters ----------------------------------------
266 # Enable TLS hooks so that the TLS module can be used
270 # -------------------- Custom Parameters ------------------------------------
271 # These parameters can be modified runtime via RPC interface,
272 # read the documentation of cfg_rpc module.
274 # Session Timer parameters, RFC 4028
276 # Default session interval used by the proxy if the UAC does not support
277 # session timer. Set it to "0" to disable session timer proxy support.
279 session_timer.default = "1800" desc "default session interval (in s)"
281 # Minimum session interval accepted by the proxy, it must not be less
284 session_timer.min_se = "90" desc "minimum session interval (in s)"
288 # Whether to enable or disable the rtp proxy. Possible values are:
289 # "0" -- always disable
290 # "1" -- always enable regardless of whether UAC or UAS is behind NAT
291 # "detect" -- detect whether the UAC or the UAS is behind NAT,
292 # and enable the rtp proxy when necessary
294 #DEBCONF-RTP_ENABLE-START
295 rtp_proxy.enabled = "detect" desc "indicates whether the RTP Proxy is enabled or not (0/1/detect)"
296 #DEBCONF-RTP_ENABLE-END
298 # ------------------ Module Loading -----------------------------------------
299 #!ifdef LOCAL_TEST_RUN
300 loadpath "modules:modules_s"
302 loadpath "/usr/lib/sip-router/modules:/usr/lib/sip-router/modules_s"
305 # load a SQL database for authentication, domains, user AVPs etc.
306 loadmodule "db_mysql"
307 #loadmodule "postgres"
314 loadmodule "registrar"
331 loadmodule "nathelper"
333 loadmodule "speeddial"
344 # ----------------- Declaration of Script Flags -----------------------------
346 FLAG_ACC : 1, # the request will be recorded by ACC
347 FLAG_FAILUREROUTE : 2, # we are operating from the failure route
348 FLAG_NAT : 3, # the UAC is behind a NAT
349 FLAG_REPL_ENABLED : 4, # REGISTER replication is enabled if set
350 FLAG_TOTAG : 5, # request has a To tag
351 FLAG_PSTN_ALLOWED : 6, # the user is allowed to use the PSTN
352 FLAG_DONT_RM_CRED : 7, # do not remove the credentials
353 FLAG_AUTH_OK : 8, # authentication succeeded
354 FLAG_SERWEB_RSVD1 : 9, # bit reserved for use with serweb
355 FLAG_SERWEB_RSVD2 : 10, # bit reserved for use with serweb
356 FLAG_SESSIONTIMER : 11, # indicates that the UAC supports Session Timer
357 FLAG_RR_DONE : 12, # the request got already one RR header
358 FLAG_RTP_PROXY : 13, # the RTP proxy is turned on
359 FLAG_NAT_REG : 14, # the UAC behind NAT, stored in location record
360 FLAG_INIT_DLG : 15, # init INVITE dialog
361 FLAG_REVERSE_DIR : 16, # set if request goes callee -> caller direction, requires rr.append_fromtag=1
362 FLAG_ACC_MISSED : 17, # the missed call will be recorded by ACC
363 FLAG_USRLOC_FWD : 18, # usrloc based forward
364 FLAG_NEXT_ROUTE : 19; # there is a route remaining
367 dialog_cookie; # attribute will be stored in Route headers
369 # ----------------- Module-specific Parameters ------------------------------
371 # path to the database
374 modparam("speeddial|auth_db|usrloc|domain|uri_db|gflags|avp_db|db_ops",
375 "db_url", "mysql://ser:heslo@localhost/ser")
378 # specify the path to your database for accounting
379 #DEBCONF-DBURLACC-START
380 modparam("acc_db", "db_url", "mysql://ser:heslo@localhost/ser")
381 #DEBCONF-DBURLACC-END
386 # Database access mode: 0 -- memory cached, 1 -- write through,
387 # 2 -- delayed write. 1 is generally safer than 2. 2 can help
388 # to survive peaks in load. However, it creates delayed peaks that can
389 # impair request-processing latency later (usrloc would have to be
390 # re-redesigned more lock-free to avoid it).
391 #DEBCONF-DBMODE-START
392 modparam("usrloc", "db_mode", 1)
395 # Don't delete expired records from database on a per-contact basis -- that
396 # results in bulky DB operations and can lead to synchronization issues
397 # in server farm when for a time a server doesn't obtain re-reregistrations
398 modparam("usrloc","db_skip_delete",1)
403 # Maximum expires time. Forces users to re-register every 10 min.
404 modparam("registrar", "max_expires", 600)
406 # Minimum expires time. Even if they try, clients cannot register
407 # for a shorter time than this.
408 modparam("registrar", "min_expires", 240)
410 # Identify natted contacts using a flag.
411 modparam("registrar", "load_nat_flag", "FLAG_NAT_REG")
412 modparam("registrar", "save_nat_flag", "FLAG_NAT_REG")
414 # Maximum number of contacts.
415 modparam("registrar", "max_contacts", 10)
420 #modparam("auth_db", "calculate_ha1", yes)
421 #modparam("auth_db", "password_column", "password")
423 # Minimize replay-attack window.
424 modparam("auth", "nonce_expire", 10)
426 # Enable/disable extra authentication checks using the following modparams.
427 # The values are: 1 -- Request-URI, 2 -- Call-ID, 4 -- From tag,
428 # 8 -- source IP. The options are disabled by default.
430 # For REGISTER requests we hash the Request-URI, Call-ID, and source IP of the
431 # request into the nonce string. This ensures that the generated credentials
432 # cannot be used with another registrar, user agent with another source IP
433 # address or Call-ID. Note that user agents that change Call-ID with every
434 # REGISTER message will not be able to register if you enable this.
435 #modparam("auth", "auth_checks_register", 11)
437 # For dialog-establishing requests (such as the original INVITE, OPTIONS, etc)
438 # we hash the Request-URI and source IP. Hashing Call-ID and From tags takes
439 # some extra precaution, because these checks could render some UA unusable.
440 #modparam("auth", "auth_checks_no_dlg", 9)
442 # For mid-dialog requests, such as re-INVITE, we can hash source IP and
443 # Request-URI just like in the previous case. In addition to that we can hash
444 # Call-ID and From tag because these are fixed within a dialog and are
445 # guaranteed not to change. This settings effectively restrict the usage of
446 # generated credentials to a single user agent within a single dialog.
447 #modparam("auth", "auth_checks_in_dlg", 15)
449 # Deal with clients who can't do qop properly
450 modparam("auth", "qop", "")
451 #DEBCONF-AUTHSECRET-START
452 modparam("auth", "secret", "aqwedrftredswqwddcft")
453 #DEBCONF-AUTHSECRET-END
458 # Add value to lr param to make some broken UAs happy.
459 modparam("rr", "enable_full_lr", 1)
461 # Limit the length of the AVP cookie to necessary attributes only
462 modparam("rr", "cookie_filter", "(account|rproxy|stimer|dialog_id)")
464 # You probably do not want that someone can simply read and change
465 # the AVP cookie in your Routes, thus should really change this
467 modparam("rr", "cookie_secret", "sgsatewgdbsnmpoiewh")
469 # The ftag Route parameter may be used to easily determine if a BYE
470 # is coming from caller or callee, but we prefer shorter messages
471 # Enable when FLAG_REVERSE_DIR is to be used
472 modparam("rr", "append_fromtag", 0)
477 # Load global attributes.
478 modparam("gflags", "load_global_attrs", 1)
483 # Load domain attributes.
484 modparam("domain", "load_domain_attrs", 1)
489 # By default, ctl listens on unixs:/tmp/sip-router_ctl if no other address is
490 # specified in modparams; this is also the default for sercmd.
491 modparam("ctl", "binrpc", "unixs:/tmp/ser_ctl")
492 # Listen on the "standard" fifo for backward compatibility.
493 modparam("ctl", "fifo", "fifo:/tmp/ser_fifo")
494 # Listen on tcp on localhost.
495 modparam("ctl", "binrpc", "tcp:127.0.0.1:2046")
500 # Failed transactions (those with negative responses) should be logged, too.
501 modparam("acc_db", "failed_transactions", 1)
503 # If you don't want to have accounting entries written into the database,
504 # comment the next line out.
505 modparam("acc_db", "log_flag", "FLAG_ACC")
506 # seems "log_flag" and "log_flag_missed" cannot share the same flag!
507 modparam("acc_db", "log_missed_flag", "FLAG_ACC_MISSED")
509 # if you would like to customize your CDRs, do it here....
510 #modparam("acc_db", "attrs",
511 # "$f.sop_billing_category,$f.isPrepaidCustomer,$f.sop_cf_orig_uid")
516 # Do not restart the resend timer with each reply. (See INBOUND route
518 modparam("tm", "restart_fr_on_each_reply", 0)
524 # Use a sub-route. This is a lot safer then relying on the request method
525 # to distinguish HTTP from SIP
526 modparam("xmlrpc", "route", "XMLRPC");
533 #DEBCONF-RTTPPROXY-START
534 modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:22222")
535 #DEBCONF-RTTPPROXY-END
537 # TCP keepalives as simple as CRLF
538 modparam("nathelper", "natping_crlf", 0)
540 # How often to send a NAT ping. Set this to 0 to turn NAT ping off.
541 #DEBCONF-NATPING_INTERVAL-START
542 modparam("nathelper", "natping_interval", 15)
543 #DEBCONF-NATPING_INTERVAL-END
545 # Only ping contacts that have the NAT flag set.
546 modparam("nathelper", "ping_nated_only", 1)
548 # Send an OPTIONS SIP request as NAT ping. If this is not set, a simple
549 # 4-byte ping is used.
550 modparam("nathelper", "natping_method", "OPTIONS")
552 # Temporary statefull natping test (only in future versions)
553 #modparam("nathelper", "natping_stateful", 1)
557 modparam("exec", "time_to_kill", 200);
558 modparam("exec", "setvars", 0);
562 # Register route ON_1MIN_TIMER to be called every minute.
563 modparam("timer", "declare_timer",
564 "ON_1MIN_TIMER=ON_1MIN_TIMER,60000,slow,enable");
568 #!ifdef LOCAL_TEST_RUN
569 modparam("tls", "config", "./modules/tls/tls.cfg");
571 modparam("tls", "config", "tls.cfg");
577 modparam("db_ops", "declare_handle", "reload")
578 modparam("db_ops", "declare_handle", "gattr_reload")
581 # ------------------------- Request Routing Logic --------------------------
583 # Main request route.
585 # Each request starts here.
589 # if you have a PSTN gateway just un-comment the follwoing line and
590 # specify the IP address of it to route calls to it.
593 # Alternatively (even better), set it as global persistent parameter
594 # using serweb or ser_attrs). If using a PSTN GW, per-subscriber
595 # options must ($gw_acl) or may (asserted_id) be set to enable calls
596 # to PSTN. If email-like URIs are used, having a URI alias for
597 # processing incoming PSTN-to-ip requests may be useful, too.
598 # Important: the script is assuming one global pstn-gw for all
599 # domains! Failure to allow gw_ip to be a domain-specic attribute
600 # would result in security gaps (onsend_route checks only for one
603 # First, do some initial sanity checks.
606 # Bypass the rest of the script for CANCELs if possible.
609 # Check if the request is routed via Route header.
610 route(PROCESS_ROUTES);
615 # Answer OPTIONS requests to our system.
616 route(OPTIONS_REPLY);
618 # Enforce domain policy.
619 route(DOMAIN_POLICY);
621 # Handle REGISTER requests.
624 # From here on we want to know who is calling.
625 route(AUTHENTICATION);
627 # We are finished with all the precaution work -- let's
628 # try to locate the callee. The first route that matches
629 # "wins" and relays the request. If none matches, SER will
632 # Check if we should be outbound proxy for a local user.
635 # Redirect in case user dialed a speed dial entry.
638 # Place various site-specific routes here.
639 route(SITE_SPECIFIC);
641 # Check if the request is for a local user.
644 # There is SIP user for the called address. Before trying PSTN,
645 # you may have to convert the adress, for instance by using
649 # Last resort: if none of the previous route has found
650 # the recepient, try PSTN.
654 sl_reply("404", "No route matched");
657 # Forward a request to the destination set.
661 # If this is called from the failure route we need to add a new
663 if (isflagset(FLAG_FAILUREROUTE)) {
664 if (!append_branch()) {
665 t_reply("500", "Too many branches");
670 # If this is an initial INVITE (without a To-tag) we might try
671 # another target (call forwarding or voicemail) after receiving
673 if (isflagset(FLAG_INIT_DLG)) {
674 t_on_failure("FAILURE_ROUTE");
677 # Always use the reply route to check for NATed UAS.
678 t_on_reply("REPLY_ROUTE");
680 # Remove credentials to keep requests shorter
681 if (isflagset(FLAG_AUTH_OK) && !isflagset(FLAG_DONT_RM_CRED) ) {
682 consume_credentials();
685 # Activate the RTP proxy as the second last step because it modifies the
686 # body but also sets an dialog AVP cookie.
689 # Insert a Record-Route header into all requests.
690 # This has to be done as one of the last steps to include all the
691 # RR cookies which might have been created during the script run.
696 if (isflagset(FLAG_FAILUREROUTE)) {
697 # XXX This should be replaced with
698 # t_reply_error() similar to sl_reply_error()
699 # in order to return the proper failure code.
700 # Only, there is no such function yet.
701 t_reply("500", "Request cannot be forwarded");
711 # Perform initial checks on an incoming request.
713 # Rejects the request if it fails any of the checks.
717 # Messages with a Max-Forwards header of zero.
718 if (!mf_process_maxfwd_header("10")) {
719 sl_reply("483","Too Many Hops");
723 # Set flag for use in the onsend route (because it does not
724 # allow to use "select" statements)
729 # Check if the UAC is NATed and fix the message accordingly
730 route(UAC_NAT_DETECTION);
732 # Activate accounting for all initial INVITEs. In-dialog requests
733 # are accounted by a RR cookie (see below).
734 # It should work also when the call has been already forked at a previous router
735 if (method == "INVITE" && !isflagset(FLAG_TOTAG)) {
736 $dialog_id = @sys.unique; # make unique dialogid
738 setflag(FLAG_ACC_MISSED);
739 setflag(FLAG_INIT_DLG);
740 } else if (isflagset(FLAG_TOTAG) && @hf_value.route[0].params.ftag != @from.tag) {
741 setflag(FLAG_REVERSE_DIR); # callee -> caller
744 # if needed then we MUST put after force_rport() which is located in NAT_DETECTION!!!
745 # also must be called after FLAG_ACC is set !!!
746 # Check t_reply() vs. sl_reply() usage in script
748 # sl_reply("500", "Internal tm error");
752 # Set flag and use it instead of the attribute.
754 setflag(FLAG_REPL_ENABLED);
759 # Reply OPTIONS requests sent to the proxy itself.
763 # OPTIONS requests without a username in the Request-URI but one
764 # of our domains or IPs are addressed to the proxy itself and
765 # can be answered statelessly.
766 if (method == "OPTIONS" && strempty(@ruri.user) &&
767 (uri == myself || $t.did != ""))
775 # Check if the sender of the request is behind a NAT device. If so,
776 # fix the request so that other devices can talk to the sender nonetheless.
778 route[UAC_NAT_DETECTION]
780 # Lots of UAs do not include the rport parameter in there Via
781 # header, so we put it there regardless.
784 # If a reliable transport was used store the connection internally
785 # so that SERs core can re-use the connection later.
786 if (proto==TCP || proto == TLS)
791 # Check if the request contains hints for a NATed UAC. Also, try to
792 # rewrite contacts using maddr. Using maddr is a really dubious
793 # technique and we better replace such with transport address.
794 # Downside: it fails for clients fronted by another server, in
795 # which case a valid contact we dislike because of maddr will be
796 # substituted inapproprietely (e.g., WM from other domains will
797 # fail). If you are worried about that, remove tests for maddr and
798 # recompile SER using HONOR_MADDR. Also note that rewriting
799 # contacts may possibly lead to client denying subseqent requests
800 # to them because they don't recognized fixed contacts as their
801 # own. Should you encounter such a case, a possible solution
802 # would be to store the original information as a contact parameter
803 # and restore it on its way back.
805 # In case of UDP we test for
806 # - private IPs in Contact
807 # - mismatch of transport IP and IP in Via
808 # - mismatch of transport port and port in Via
809 # in all other cases we skip the port test, because lots of clients
810 # do not correctly advertise their emphemeral port number in their Via
811 # header in case of reliable transports (although they are not behind
814 # Warning: if you are dealing with SIP implementations which are
815 # running on public IP and do as-symmertic signaling for whatever
816 # reason the following check will make their signaling symmetric.
817 # If you need to support as-symmertic signaling reduce the following
818 # nat_uac_test for UDP to "3" or even "1".
819 if ((proto == UDP && nat_uac_test("19")) ||
820 (nat_uac_test("3")) ||
821 (@hf_value["contact"] != "" && @contact.uri.params.maddr != ""))
824 if (method == "REGISTER") {
825 # Prepare the Contact so that the registrar module
826 # saves the source address and port as well.
827 fix_nated_register();
830 # Overwrite the Contact to allow proper in-dialog
832 # but do not override if there is already a proxy in the path, we'll route by record-route,
833 # RURI responsibility takes to previous proxy
834 # TODO: shouldn't we rather limit to methods which are dialog aware (INVITE, UPDATE, SUBSCRIBE, ..)
835 if (strempty(@hf_value.record_route) || (@hf_value["contact"]!="" && @contact.uri.params.maddr!="")) {
844 # Check if the receiver of the request is behind a NAT device. If so,
845 # fix the Contact header to allow proper routing of in-dialog requests.
846 route[UAS_NAT_DETECTION]
848 # Fix the Contact in the reply if it contains a private IP to
849 # allow proper routing of in-dialog messages.
850 # Do the same if the contact is maddred.
852 # But skip 3XX responses, because we do not know the right IP for that,
853 # even if they contain private IPs.
854 if (status=~"(3[0-9][0-9])") {
858 # prevent contact overwriting when a proxy between ser and UAS.
859 # We get it from record-route but it's rather difficult or
860 # do it only for UAS which is registered in usrloc database and has no
862 # Note: destination forced by $fwd_always_target is not NAT detected and contact left untouched!
863 if (isflagset(FLAG_INIT_DLG) && !isflagset(FLAG_USRLOC_FWD)) {
866 # for in-dialog requests we get it easily because it provides loose_route()
867 if (!isflagset(FLAG_INIT_DLG) && isflagset(FLAG_NEXT_ROUTE)) {
871 # Prevent that we over-write the Contact with the IP of our proxy when
872 # the reply loops through ourself.
873 if (src_ip == myself) {
877 # In this case we check only if the Contact URI contains a private
878 # IP, because the Via header contains only informations from the UAC.
879 # Additionally we check if the port in the Contact URI differs from
880 # the port of the transport to catch UAS or ALG which put the public
881 # IP address into the Contact header, but "forget" about the port.
883 # Warning: if you are dealing with SIP implementations which are
884 # running on public IP and do as-symmertic signaling for whatever
885 # reason the following check will make their signaling symmetric.
886 # If you need to support as-symmertic signaling reduce the following
887 # nat_uac_test for UDP to just "1".
888 if ( (proto == UDP && nat_uac_test("33")) ||
889 (nat_uac_test("1") ||
890 (@hf_value["contact"] != "" && @contact.uri.params.maddr != "")))
892 # TODO: check if no proxy between UAS&myself
898 # Activates RTP proxy if necessary.
902 if (@cfg_get.rtp_proxy.enabled == "0") {
903 # RTP Proxy is disabled
905 } else if (@cfg_get.rtp_proxy.enabled == "detect") {
906 if (!isflagset(FLAG_NAT)) {
907 # If no NAT is involved we don't have to do here anything.
910 } else if (@cfg_get.rtp_proxy.enabled != "1") {
911 # This is not a valid setting
912 xlog("L_ERR", "Unknown option for rtp_proxy.enabled: %@cfg_get.rtp_proxy.enabled\n");
914 } # else rtp proxy is permanently enabled
916 # If the message terminates a dialog for which the RTP proxy
917 # was turned on, turn it off again.
918 if ((method == "BYE" && isflagset(FLAG_RTP_PROXY)) ||
919 (method == "CANCEL")) {
921 append_hf("P-RTP-Proxy: Off\r\n");
925 # Turn the RTP proxy on for INVITEs and UPDATEs, if they
927 if (((method=="INVITE" || method == "UPDATE") && @msg.body != "")
928 && !isflagset(FLAG_RTP_PROXY))
930 force_rtp_proxy('r');
931 append_hf("P-RTP-Proxy: On\r\n");
932 setflag(FLAG_RTP_PROXY);
934 setavpflag($rproxy, "dialog_cookie");
939 # Handling of Route headers
941 route[PROCESS_ROUTES]
943 # subsequent messages withing a dialog should take the
944 # path determined by the Route headers.
946 if (!defined $dialog_id) {
947 $dialog_id = $t.dialog_id; # there is only 1 dialog_id
949 if (@rr.next_route != "") {
950 setflag("FLAG_NEXT_ROUTE");
952 xlog("L_DEBUG", "\n%mb\n\ndialogid -/from/to=%$dialog_id/%$f.dialog_id/%$t.dialog_id");
953 if (method == "INVITE" || method == "UPDATE" || method == "ACK" || method == "BYE") {
954 if (!defined $dialog_id) {
955 sl_reply("400", "Missing cookie");
960 # Mark routing logic in request.
961 append_hf("P-hint: rr-enforced\r\n");
963 # If the Route contained the accounting AVP cookie we
964 # set the accounting flag for the acc_db module.
965 # This is more for demonstration purpose as this could
966 # also be solved without RR cookies.
967 # Note: this means all in-dialog request will show up in
968 # the accounting tables, so prepare your accounting software
970 if ($account == "yes") {
972 setflag(FLAG_ACC_MISSED);
975 # Restore the RTP proxy flag if present
976 if ($rproxy == "1") {
977 setflag(FLAG_RTP_PROXY);
980 # Restore Session Timer flag and headers.
981 if ( defined $stimer && ($stimer != "0")) {
982 route(SESSION_TIMER);
985 # Some broken devices overide the dialog route set with the
986 # Record-Route headers from each in-dialog request. So, we
987 # better add Record-Route headers again. If we call
988 # record_route() after loose_route(), the AVP cookies are
989 # restored automatically. Additionally, there is a scenario
990 # where Record-Route headers are necessary if an initial
991 # SUBSCRIBE is forked.
993 # Note that here we forward before authentication checks
994 # are executed. Generally, we only authenticate
995 # out-of-dialog requests. Some in-dialog requests can't be
996 # authenticated at all, see the call-forwarding example in
1005 # Add a Record-Route header
1009 if (!isflagset(FLAG_RR_DONE) && method != "REGISTER") {
1010 # We record-route all messages to make sure that
1011 # subsequent messages will go through our proxy. This is
1012 # particularly good if upstream and downstream entities
1013 # use different transport protocols.
1015 # If the ACC flag is set, store this in a Record-Route
1016 # AVP cookie. This is more for demonstration purposes.
1017 if (isflagset(FLAG_ACC)) {
1019 setavpflag($account, "dialog_cookie");
1022 setavpflag("$f.dialog_id", "dialog_cookie");
1024 # Insert the RR header.
1027 # This flag allows to call this route several times
1028 # without inserting several RR headers.
1029 setflag(FLAG_RR_DONE);
1034 # Look up the domains of the caller and the callee.
1038 # Check whether the caller is from a local domain.
1039 lookup_domain("$fd", "@from.uri.host");
1041 # Check whether the callee is at a local domain
1042 lookup_domain("$td", "@ruri.host");
1046 # Check domain usage policies and reject illegal requests.
1048 route[DOMAIN_POLICY]
1051 # If we don't know the domain of the caller nor the domain of the
1052 # callee, somone tries to use our proxy as a relay. However, we
1053 # can only apply this check out-of-dialog requests without a To
1054 # tag. In some cases such as call-forwarding, subsequent requests
1055 # may not include served domain neither as origination nor
1056 # destination (a@A calls b@B who forwards to c@C. A BYE by c@C is
1057 # then From b@B and To a@A. There is no mentioning of c@C despite
1058 # legitimate behaviour of c@C).
1059 if (!isflagset(FLAG_TOTAG) && strempty($t.did) && strempty($f.did)) {
1060 sl_reply("403", "Relaying Forbidden");
1070 # Process only REGISTERs here.
1071 if (method != "REGISTER") {
1075 # If this is a replica (sent to the multicast address), trust it to
1076 # be secure and store it in usrloc
1077 if (dst_ip==224.0.1.75) {
1078 if (!isflagset(FLAG_REPL_ENABLED)) {
1079 # Multicast replication administratively disabled.
1084 # Read marker from master
1085 if (search("^Repl-Marker: nated")) {
1089 # If the replicating server added its own server id to the
1090 # request, obtain the value and store it in an attribute.
1091 # This is used by registrar.
1092 $server_id = @msg.header["SER-Server-ID"];
1094 # Assume URI in form of UID@mydomain and store contacts
1095 # under this UID. Note that this only works if local policy
1096 # causes UIDs to have form compliant to RFC3261 URI
1099 $tu.uid = @ruri.user;
1100 if (isflagset(FLAG_NAT)) {
1101 setflag(FLAG_NAT_REG);
1103 if (!save_mem_nr("location")) {
1104 log(1, "Error while saving replicated REGISTER.\n");
1109 # This is a REGISTER request received from the UA. Remove
1110 # our internal header fields if they are present. The may
1111 # have been added maliciously.
1112 remove_hf("SER-Server-ID");
1113 remove_hf("Repl-Marker");
1116 # Check if the REGISTER if for one of our local domains.
1117 if (strempty($t.did)) {
1118 sl_reply("403", "Register Forwarding Forbidden");
1122 # The REGISTER target is in the To header, so reload the domain.
1123 if (!lookup_domain("$td", "@to.uri.host")) {
1124 sl_reply("404", "Unknown Domain");
1128 # Useful for clients that ignore expires in 200 (OK). This is an
1129 # attempt to keep them sticking to our value of 600.
1130 append_to_reply("Expires: 600\r\n");
1131 append_to_reply("Min-Expires: 240\r\n");
1133 # We want only authenticated users to be registered.
1134 if (!www_authenticate("$fd.digest_realm", "credentials")) {
1136 sl_reply("500", "Internal Server Error");
1138 else if ($? == -3) {
1139 sl_reply("400", "Bad Request");
1142 if ($digest_challenge != "") {
1143 append_to_reply("%$digest_challenge");
1145 sl_reply("401", "Unauthorized");
1150 # Check if the authenticated user is the same as the target user.
1151 if (!lookup_user("$tu.uid", "@to.uri")) {
1152 sl_reply("404", "Unknown user in To");
1156 # the authentication ID does not match the ID in the To header
1157 if ($f.uid != $t.uid) {
1158 sl_reply("403", "Authentication and To-Header mismatch");
1162 # Check if the authenticated user is the same as the request
1163 # originator. You may uncomment it if you care, which URI is in
1165 #if (!lookup_user("$fr.uid", "@from.uri")) {
1166 # sl_reply("404", "Unknown user in From");
1169 #if ($fu.uid != $fr.uid) {
1170 # sl_reply("403", "Authentication and From-Header mismatch");
1174 if (isflagset(FLAG_NAT)) {
1175 setflag(FLAG_NAT_REG);
1177 # Everything is fine. Store the binding.
1178 if (!save_contacts("location")) {
1179 sl_reply("400", "Invalid REGISTER Request");
1182 # do not delete the following 3 lines, they are used by debconf
1183 #DEBCONF-REPLICATION1-START
1185 #DEBCONF-REPLICATION1-END
1186 if (isflagset(FLAG_REPL_ENABLED)) {
1187 if (isflagset(FLAG_NAT)) {
1188 append_hf("Repl-Marker: nated\r\n");
1190 # Append this server's unique ID to the request
1191 append_hf_value("SER-Server-ID", "%@sys.server_id");
1192 # We are multicasting a successful REGISTER to all proxies
1193 # on the multicast network to replicate the contact
1194 # addresses to all of them. In case they share the same IP
1195 # address (VIP) it is important to set the sending IP
1196 # address to an unshared one (in the future a special mcast
1197 # module may use unbound sockets for sending and leave
1198 # the source IP address decision up to kernel routing
1200 #DEBCONF-REPL_SEND_ADDR-START
1201 force_send_socket(udp:127.0.0.1);
1202 #DEBCONF-REPL_SEND_ADDR-END
1203 # Put the UID in the Request-URI so that it doesn't have to
1204 # be looked up in the database by all multicast receivers.
1205 attr2uri("$tu.uid","user");
1206 forward_udp(224.0.1.75,5060);
1208 #DEBCONF-REPLICATION2-START
1210 #DEBCONF-REPLICATION2-END
1216 # Authentication of request originators claiming to belong to one of our
1219 route[AUTHENTICATION]
1221 # CANCELs and ACKs cannot be challenged.
1222 if (method=="CANCEL" || method=="ACK") {
1226 # Requests from non-local to local domains should be permitted.
1227 # Remove this if you want a walled garden.
1228 if (strempty($f.did)) {
1232 # Gateways are usually not able to authenticate for their requests.
1233 # You have to trust them base on some other information such as the
1234 # source IP address.
1235 # WARNING: If at all this is only safe in a local network!
1236 if (src_ip == $gw_ip) {
1240 if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
1242 sl_reply("500", "Internal Server Error");
1244 else if ($? == -3) {
1245 sl_reply("400", "Bad Request");
1248 if (defined $digest_challenge && $digest_challenge != "") {
1249 append_to_reply("%$digest_challenge");
1251 sl_reply("407", "Proxy Authentication Required");
1256 # Check if the UID derived from authentication matches that from
1258 if (!lookup_user("$fr.uid", "@from.uri")) {
1259 sl_reply("403", "Fake Identity");
1262 if ($fu.uid != $fr.uid) {
1263 sl_reply("403", "Fake Identity");
1266 setflag(FLAG_AUTH_OK);
1268 # Load the user attributes of the caller.
1269 load_attrs("$fu", "$f.uid");
1273 # Process request targeted to non-local domains.
1277 # If a local user calls to a foreign domain we play outbound
1279 # Comment this out if you want a walled garden.
1280 if ($f.did != "" && strempty($t.did)) {
1281 append_hf("P-hint: outbound\r\n");
1287 # Process speeddial addresses.
1291 # If the caller is local and uses two digits only, we redirect the
1292 # UA to the real target.
1293 if ($fd.did != "" && uri =~ "sip:[0-9][0-9]@") {
1294 if (sd_lookup("speed_dial")) {
1295 sl_reply("302", "Speed Dial Redirect");
1298 sl_reply("404", "Speed Dial Not Found");
1305 # Process requests targeted to a local user.
1309 # lets see if know the callee
1310 if (!lookup_user("$tu.uid", "@ruri")) {
1314 # Load the attributes of the callee.
1315 load_attrs("$tu", "$t.uid");
1317 # You can check if the called URI is in fact an alias like this.
1318 #if (! $tu.uri_canonical) {
1319 # # If the alias URI has different attributes, you can load
1320 # # them into the URI track like this.
1321 # load_attrs("$tr", "@ruri");
1324 # Check for call forwarding of the callee.
1325 # Note: The forwarding target has to be full routable URI
1327 if (defined $tu.fwd_always_target && $tu.fwd_always_target != "") {
1328 attr2uri("$tu.fwd_always_target");
1330 # If we are forwarding to ourselves, don't remove
1331 # credentials. Otherwise the request would be challenged
1333 # Note: This doesn't apply to failure_route which may
1334 # still be problematic -- credentials are already
1335 # removed when we forward. Consider using a 3xx.
1336 lookup_domain("$td", "@ruri.host");
1337 if (defined $t.did && $t.did != "") {
1338 setflag(FLAG_DONT_RM_CRED);
1343 # Native SIP destinations are handled using the usrloc database.
1344 if (lookup_contacts("location")) {
1345 append_hf("P-hint: usrloc applied\r\n");
1347 # destination is behind NAT
1348 if (isflagset(FLAG_NAT_REG)) {
1349 setflag(FLAG_NAT); /* client was behind NAT when made registration */
1351 # We set the tm module timers according to the prefences
1352 # of the callee (avoid too long ringing of his phones).
1353 # Note1: Timer values have to be in ms now!
1354 # Note2: This makes even more sense if you switch to a
1355 # voicemail from the FAILURE_ROUTE below.
1356 if ($t.fr_inv_timer) {
1358 t_set_fr("$t.fr_inv_timer", "$t.fr_timer");
1361 t_set_fr("$t.fr_inv_timer");
1365 # This enables session timer support as long as one side
1366 # supports it. If you want to have session timmer support
1367 # only for calls from your PSTN gateway but not between pure
1368 # VoIP calls you can remove the comment marks from the if
1369 # clause in the next line and closing bracket below.
1370 # WARNING: If at all you should trust IP addresses only in
1371 # your local network!
1372 #if (src_ip == $gw_ip) {
1373 route(SESSION_TIMER);
1379 sl_reply("480", "Temporarily unavailable");
1385 # Process calls for PSTN.
1389 # Check some conditions first:
1390 # PSTN is available for our own users only.
1391 if (strempty($f.did)) {
1395 # If the attribute $gw_ip isn't set, there is no PSTN service
1397 if (!defined $gw_ip) {
1401 # And finally, the username of the Request-URI must look like
1403 if (!uri =~ "^sips?:\+?[0-9]{3,18}@") {
1407 # You may have to convert the number in the Request-URI into a
1408 # format that is accepted by your gateway here.
1410 # Check permissions of the caller for initial INVITEs.
1411 if (isflagset(FLAG_INIT_DLG)) {
1412 if ($f.gw_acl != "1") {
1413 sl_reply("403", "PSTN Not Permitted");
1418 # If the attribute $asserted_id is set, we add its contents as a
1419 # Remote-Party-ID header.
1420 # Depending on your gateway, you may have to add a
1421 # P-Asserted-Identity header here instead.
1422 if (defined $asserted_id) {
1423 xlset_attr("$rpidheader",
1424 "<sip:%$asserted_id@%@ruri.host>;screen=yes");
1425 replace_attr_hf("Remote-Party-ID", "$rpidheader");
1428 # Enable Session Timer support with the gateway.
1429 route(SESSION_TIMER);
1431 # Replace the domain part of the Request-URI with the value from
1432 # the attribute and send it out.
1433 attr2uri("$gw_ip", "domain");
1435 # Set the PSTN_ALLOWED flag. This will be checked on the
1437 setflag(FLAG_PSTN_ALLOWED);
1442 # Try to process CANCEL requests quickly.
1446 if (method == CANCEL) {
1447 # t_relay_cancel() will stop processing if a matching
1449 xlog("L_DEBUG", "catching cancel dialogid=%$dialog_id\n");
1450 if (!t_relay_cancel()) {
1451 # An INVITE was found but some error occurred.
1452 sl_reply("500", "Internal Server Error");
1455 # Bad luck, no corresponding INVITE was found, we have to
1456 # continue with the script.
1461 # Site specific policy.
1463 route[SITE_SPECIFIC]
1465 # This is only relevant for requests for one of our domains.
1466 if (strempty($t.did)) {
1470 # Do site specific routing such as peering.
1472 if (uri=~"^sip:000777") {
1473 rewritehostport("sems01.iptel.org:5074");
1478 # Process Session-Timer.
1480 route[SESSION_TIMER]
1482 # We are only interested in session establishment or session
1485 if (method != "INVITE" && method != "UPDATE") {
1489 # Let's check if the Session-Expires header is already present.
1490 if (@hf_value.session_expires != "") {
1491 # Compare the Session-Expires header value with the
1492 # configured Min-SE.
1493 eval_push("x:%@hf_value.session_expires.uri");
1494 eval_oper("(int)", -1);
1495 eval_push("x:%@cfg_get.session_timer.min_se");
1496 eval_oper("(int)", -1);
1497 eval_oper(">=", -2);
1499 # Let's check for the Suported header.
1500 if (hf_value_exists("Supported", "timer")) {
1501 # The UAC supports Session-Timer, so we
1502 # only need to take a look at the values
1503 if (@eval.pop[-1] == "0") {
1504 # Session interval is lower than the
1506 append_to_reply("Min-SE: %@cfg_get.session_timer.min_se\r\n");
1507 sl_reply("422", "Session Interval Too Small");
1511 # We store the session expires value for the reply
1512 # route and mark the attribute for inserting as
1513 # Record-Route cookie.
1514 $stimer = @hf_value.session_expires.uri;
1515 setavpflag($stimer, "dialog_cookie");
1517 # Set the session timer flag that indicates the
1518 # UAC supports the extension.
1519 setflag(FLAG_SESSIONTIMER);
1522 # Session epxires was already inserted by some other
1524 if (@eval.pop[-1] == "0") {
1525 # Session interval is lower than the
1526 # configured Min-SE. There is no point in
1527 # sending 422 response, because the UAC
1528 # does not support the extension, the values
1529 # can be corrected instead.
1530 assign_hf_value("Session-Expires",
1531 "%@cfg_get.session_timer.min_se");
1532 remove_hf_value("Min-SE");
1533 append_hf_value("Min-SE",
1534 "%@cfg_get.session_timer.min_se");
1539 # No Session Timer is requested yet, neither by UAC nor by
1541 if (@cfg_get.session_timer.default != "0") {
1542 # Add a Session Expires header to see if the UAS
1543 # supports Session Timer. We do not insert a
1544 # Required header because then the call might fail.
1545 append_hf_value("Session-Expires",
1546 "%@cfg_get.session_timer.default");
1547 if (@cfg_get.session_timer.min_se != "90") {
1548 append_hf_value("Min-SE",
1549 "%@cfg_get.session_timer.min_se");
1552 # Mark the attribute to be inserted as a
1553 # Record-Route cookie
1554 $stimer = @cfg_get.session_timer.default;
1555 setavpflag($stimer, "dialog_cookie");
1560 # Route which checks and performs ENUM queries
1564 # perform ENUM query only if the RURI contains an E.164
1565 # number as uer part
1566 if (uri =~ "sip:\+[0-9]?@") {
1567 # if the ENUM query was successful send it right
1568 # away of to the new target, otherwise do nothing
1576 # Failure route for initial INVITEs.
1578 failure_route[FAILURE_ROUTE]
1580 if (isflagset(FLAG_INIT_DLG)) {
1581 # Mark that we are operating from a failure route.
1582 setflag(FLAG_FAILUREROUTE);
1584 if (t_check_status("486|600")) {
1585 # If we received a busy and a busy target is set, forward
1587 # Note: Again, the forwarding target has to be a routeable
1588 # URI. We redirect using 3xx to avoid possible issues with
1589 # credentials (if we consumed them, they may be missing in
1590 # a loop, if we don't consume them, messages are bigger and
1592 if ($tu.fwd_busy_target != "") {
1593 attr2uri("$tu.fwd_busy_target");
1594 #attr_destination("$tu.fwd_busy_target");
1596 t_reply("302", "Redirect On Busy");
1598 # Alternatively, you could forward the request to
1599 # SEMS/voicemail here
1601 else if (t_check_status("408|480")) {
1602 # If we received no answer and the noanswer target is set,
1605 if ($tu.fwd_noanswer_target != "") {
1606 attr2uri("$tu.fwd_noanswer_target");
1607 #attr_destination("$tu.fwd_noanswer_target");
1609 t_reply("302", "Redirect On No Answer");
1612 } # if (isflagset...
1616 # Onreply route that fixes NAT in responses.
1618 onreply_route[REPLY_ROUTE]
1620 # Check and fix the Contact in the reply to
1621 # allow proper routing of in-dialog messages.
1622 route(UAS_NAT_DETECTION);
1624 # If RTP proxy was activated and this is a 18x or 2xx reply with a
1625 # body, inform RTP proxy.
1626 if (isflagset(FLAG_RTP_PROXY)
1627 && status=~"(18[03])|(2[0-9][0-9])"
1630 force_rtp_proxy('r');
1633 # Let's check for session timer support.
1634 if (isflagset(FLAG_SESSIONTIMER) && status =~ "2[0-9][0-9]") {
1635 # The UAC wanted to have a session timer.
1636 if (strempty(@hf_value.session_expires)) {
1637 # But the UAS does not support it, so we will try
1638 # to convince the UAC to do it.
1639 append_hf_value("Session-Expires",
1640 "%$stimer;refresher=uac");
1641 if (!hf_value_exists("Require", "timer")) {
1642 include_hf_value("Require", "timer");
1649 # Do some final checks before a request is sent out.
1652 # Bypass check: Eliminate requests to the PSTN gateway if they have
1653 # not passed ACL checks and are not marked with FLAG_PSTN_ALLOWED
1654 # but are dialog-initiating requests (no to-tag, no CANCEL, no ACK).
1655 # This helps to stop policy bypasses (gateway IP uploaded as a
1656 # forked contact, or a call-forwarding destination, or a DNS name,
1657 # or a preloaded route, or something else possibly)
1658 if (defined $g.gw_ip && to_ip==$g.gw_ip && !isflagset(FLAG_PSTN_ALLOWED)
1659 && !isflagset(FLAG_TOTAG)
1660 && method != "ACK" && method != "CANCEL")
1662 log(1, "ALERT: non authorized packet for PSTN, dropping...\n%mb\n");
1664 # You can't use advanced features from onsend_route.
1665 # xlog("L_ALERT", "non authorized packet for PSTN, dropping...\n%mb\n");
1669 # RFC 1918 relay protection: Useful if SER is attached to an
1670 # administrative network using private IP address space and you
1671 # wish to prevent UACs from relaying their packets there.
1673 # You will have to comment this out, if you are regularly serving
1674 # an RFC 1918 address space.
1675 if (to_ip==10.0.0.0/8 || to_ip==172.16.0.0/12
1676 || to_ip==192.168.0.0/16)
1678 log(1, "ALERT: Packet targeted to an RFC1918 address dropped\n");
1684 # Run every minute by the timer module.
1686 route[ON_1MIN_TIMER] {
1687 # Cleanup expired location records
1689 db_query("delete from location where expires<utc_timestamp()");
1690 # PostgreSQL version:
1691 #db_query("delete from location where expires<now()");
1694 # Reload domains if domain table has been changed recently.
1695 # Note: because global attributes are read-only and we can't
1696 # easily remember the "last" status, we check for changed
1697 # timestamp in 2 minute time-interval.
1699 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");
1700 # PostgreSQL version:
1701 #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");
1702 if (@db.fetch.reload.count=="1") {
1703 # Domain reload only available as fifo command.
1704 exec_msg("sercmd domain.reload");
1708 # Reload global attributes (they are cached in memory) if the contents of
1709 # the global_attrs table has been changed recently.
1710 db_query("select value from global_attrs where name='gattr_timestamp' and type=0 and cast(value as unsigned int) between unix_timestamp(now())-120 and unix_timestamp(now())", "gattr_reload");
1711 if (@db.fetch.gattr_reload.count=="1") {
1712 exec_msg("sercmd global.reload");
1714 db_close("gattr_reload");
1721 # accept xmlrpc requests only from localhost
1722 if (src_ip!=127.0.0.1
1723 #!ifdef XMLRPC_ALLOW_NET1
1724 && src_ip != XMLRPC_ALLOW_NET1
1726 #!ifdef XMLRPC_ALLOW_NET2
1727 && src_ip != XMLRPC_ALLOW_NET2
1729 #!ifdef XMLRPC_ALLOW_NET3
1730 && src_ip != XMLRPC_ALLOW_NET3
1733 xmlrpc_reply("400", "xmlrpc not allowed from this address");
1736 if (method!="POST" && method!="GET") {
1737 xmlrpc_reply("400", "unsupported HTTP method");
1740 if (msg:len >= 8192) {
1741 xmlrpc_reply("513", "request too big");
1744 #!ifdef XMLRPC_TLS_ONLY
1745 # allow xmlrpc only on TLS and only if the client certificate is valid
1747 xmlrpc_reply("400", "xmlrpc allowed only over TLS");
1750 if (@tls.peer.verified!=""){
1751 xmlrpc_reply("400", "Unauthorized");
1756 # close connection only for xmlrpclib user agents (there is a bug in
1757 # xmlrpclib: it waits for EOF before interpreting the response).
1758 if (search("^User-Agent:.*xmlrpclib"))
1760 set_reply_no_connect(); # optional