Răsfoiți Sursa

stable changes projected to developer's

Jiri Kuthan 22 ani în urmă
părinte
comite
6aeac0d81e
4 a modificat fișierele cu 804 adăugiri și 64 ștergeri
  1. 58 0
      scripts/filter_log.sh
  2. 151 21
      scripts/harv_ser.sh
  3. 32 43
      scripts/ser_mysql.sh
  4. 563 0
      scripts/serconf.sh

+ 58 - 0
scripts/filter_log.sh

@@ -0,0 +1,58 @@
+#!/bin/sh
+#
+# $Id$
+#
+# tool for filtering SIP messages from log by a RegExp
+#
+# Example of use: ./filter_msg.sh /var/log/sip/sip.1056844800 'CallId: abc'
+#
+
+
+#####################
+
+usage()
+{
+	echo "Usage: $0 <filename> <RegExp>"
+}
+
+if [ "$#" -ne 2 ] ; then
+	usage
+	exit
+fi
+
+AWK_PG='
+BEGIN {
+	IGNORECASE=1;
+	line=0;
+	msg_match=0;
+}
+
+/^#$/ {
+	line=0
+	msg_match=0
+	next
+}
+
+msg_match==1 {
+	print
+	next
+}
+
+{ 
+	if (match($0, RE)) {
+		msg_match=1;
+		# dump all accumulated lines here
+		for (i=1; i<=line; i++) print buffer[i];
+		print
+		next
+	}
+	# there are still chances for a match in following lines;
+	# keep buffering this request
+	line++
+	buffer[line]=$0
+}
+
+'
+
+
+cat $1 | awk "$AWK_PG" RE="$2"

+ 151 - 21
scripts/harv_ser.sh

@@ -24,7 +24,7 @@
 #
 
 
-LOGDIR=/var/log
+LOGDIR=/var/log/sip
 
 #####################
 
@@ -48,7 +48,7 @@ BEGIN {
     rpl300=0; rpl302=0; rpl3xx=0;
     rpl400=0; rpl401=0; rpl403=0; rpl404=0; rpl405=0;
         rpl406=0;rpl407=0;rpl408=0;rpl410=0; rpl415=0;
-        rpl476=0;rpl480=0;rpl481=0;rpl483=0;rpl486=0;rpl478=0;rpl487=0;
+        rpl476=0;rpl477=0;rpl480=0;rpl481=0;rpl482=0;rpl483=0;rpl486=0;rpl478=0;rpl487=0;
 		rpl488=0;rpl489=0;
         rpl4xx=0;
 	rpl479=0;
@@ -117,6 +117,16 @@ BEGIN {
 	ua_gphone=0;
 	ua_xlite=0;
 	ua_edial=0;
+	ua_gs=0;
+	ua_sipps=0;
+	ua_i3micro=0;
+	ua_act=0;
+	ua_ibm=0;
+	ua_xpro=0;
+	ua_hearme=0;
+	ua_draytek=0;
+	ua_st280;
+	ua_dta=0;
 	ua_xx=0;
 
 	server_cisco=0
@@ -137,6 +147,10 @@ BEGIN {
 	server_starsip=0;
 	server_ipdialog=0;
 	server_edial=0;
+	server_ma=0;
+	server_fwd=0;
+	server_columbia=0;
+	server_partysip=0;
 	server_xx=0
 
 }
@@ -331,10 +345,54 @@ ua==0 && /User-Agent:.*eDial/ {
 	ua_edial++
 	ua=1
 }
+ua==0 && /User-Agent:.*Grandstream/ {
+	ua_gs++
+	ua=1
+}
+ua==0 && /User-Agent:.*Ahead SIPPS/ {
+	ua_sipps++
+	ua=1
+}
+ua==0 && /User-Agent:.*IBM user agent/ {
+	ua_ibm++
+	ua=1
+}
+ua==0 && /User-Agent:.*Vega/ {
+	ua_vega++
+	ua=1
+}
+ua==0 && /User-Agent:.*i3micro/ {
+	ua_i3micro++
+	ua=1
+}
+ua==0 && /User-Agent:.*ACT/ {
+	ua_act++
+	ua=1
+}
+ua==0 && /User-Agent:.*X-Pro/ {
+	ua_xpro++
+	ua=1
+}
+ua==0 && /User-Agent:.*HearMe/ {
+	ua_hearme++
+	ua=1
+}
+ua==0 && /User-Agent:.*DrayTek/ {
+	ua_draytek++
+	ua=1
+}
 ua==0 && /User-Agent:.*X-Lite/ {
 	ua_xlite++
 	ua=1
 }
+ua==0 && /User-Agent:.*DTA/ {
+	ua_dta++
+	ua=1
+}
+ua==0 && /User-Agent:.*ST280/ {
+	ua_st++
+	ua=1
+}
 
 
  { comment="hack to deal with old version of ngrep (breaking in columns)"
@@ -425,6 +483,23 @@ server==0 && /Server:.*eDial/ {
 	server_edial++
 	server=1
 }
+server==0 && /Server:.*MA/ {
+	server_ma++
+	server=1
+}
+server==0 && /Server:.*Free World/ {
+	server_fwd++
+	server=1
+}
+server==0 && /Server:.*SIPUA-Columbia-University/ {
+	server_columbia++
+	server=1
+}
+server==0 && /Server:.*partysip/ {
+	server_partysip++
+	server=1
+}
+
 server==0 && /Server:/ {
 	server_xx++
 	print
@@ -568,6 +643,10 @@ reply==0 && request=0 {
     rpl476++
     next
 }
+/SIP\/2\.0 477/ {
+    rpl477++
+    next
+}
 /SIP\/2\.0 480/ {
     rpl480++
     next
@@ -576,6 +655,10 @@ reply==0 && request=0 {
     rpl481++
     next
 }
+/SIP\/2\.0 482/ {
+    rpl482++
+    next
+}
 /SIP\/2\.0 483/ {
     rpl483++
     next
@@ -704,10 +787,12 @@ END {
 	print "410 (Gone): " rpl410
 	print "415 (Unsupported Media): " rpl415
 	print "476 (no recursive registrations): " rpl476 
+	print "477 (next hop error): " rpl477
 	print "478 (Unresolveable): " rpl478 
 	print "479 (private IP): " rpl479 
 	print "480 (Unavailable): " rpl480 
 	print "481 (Call/Transaction does not exist): " rpl481 
+	print "482 (Loop Detected): " rpl482 
 	print "483 (Too Many Hops): " rpl483 
 	print "486 (Busy Here): " rpl486 
 	print "487 (Request Terminated): " rpl487
@@ -723,29 +808,59 @@ END {
 	print "6xx: " rpl6xx
 
 	print "## Request Methods"
-    print "INVITE: " invite " CANCEL: " cancel " ACK: " ack
-    print "REGISTER: " register " BYE: " bye " OPTIONS: " options " INFO: " info
-    print "MESSAGE: " message " SUBSCRIBE: " subscribe " NOTIFY: " notify
+    print "INVITE: " invite 
+	print "CANCEL: " cancel 
+	print "ACK: " ack
+    print "REGISTER: " register 
+	print "BYE: " bye 
+	print "OPTIONS: " options 
+	print "INFO: " info
+    print "MESSAGE: " message 
+	print "SUBSCRIBE: " subscribe 
+	print "NOTIFY: " notify
 
 	print "## Outbound Routes"
-	print "To imgw: " hint_imgw " To voicemail: " hint_voicemail
-	print "To bat: " hint_battest " To UsrLoc: " hint_usrloc
-	print "Outbound: " hint_outbound " To SMS: " hint_sms
-	print "To PSTN: " hint_gw " To: VM on off-line" hint_off_voicemail
+	print "To imgw: " hint_imgw 
+	print "To voicemail: " hint_voicemail
+	print "To bat: " hint_battest 
+	print "To UsrLoc: " hint_usrloc
+	print "Outbound: " hint_outbound
+	print "To SMS: " hint_sms
+	print "To PSTN: " hint_gw 
+	print "To: VM on off-line" hint_off_voicemail
 
 	print "## User Agents"
-	print "Snom: " ua_snom " MSN: " ua_msn " Mitel: " ua_mitel
-	print "Pingtel: " ua_pingtel " SER: " ua_ser " osip: " ua_osip
-	print "linphone: " ua_linphone " ubiquity: " ua_ubiquity
-	print "3com: " ua_3com " IPDialog: " ua_ipdialog " Epygi: " ua_epygi
-	print "Jasomi: " ua_jasomi " Cisco: " ua_cisco " insipid: " ua_insipid
-	print "Hotsip: " ua_hotsip " mxsf: " ua_mxsf " GrandStream: " ua_grandstream
-	print "Tellme: " ua_tellme " PocketSipM: " ua_pocketsipm 
-	print "eStara: " ua_estara " Vovida: " ua_vovida 
-	print "jSIP: " ua_jsip " Nortel: " ua_nortel " Polycom: " ua_polycom
-	print "Leader: " ua_leader " csco: " ua_csco " Nebula: " ua_nebula
-	print "MagicPPC: " ua_magicppc " SCS: " ua_scs 
-	print "SJPhone: " ua_sjphone " KPhone: " ua_kphone
+	print "Snom: " ua_snom 
+	print "MSN: " ua_msn 
+	print "Mitel: " ua_mitel
+	print "Pingtel: " ua_pingtel 
+	print "SER: " ua_ser 
+	print "osip: " ua_osip
+	print "linphone: " ua_linphone 
+	print "ubiquity: " ua_ubiquity
+	print "3com: " ua_3com 
+	print "IPDialog: " ua_ipdialog 
+	print "Epygi: " ua_epygi
+	print "Jasomi: " ua_jasomi 
+	print "Cisco: " ua_cisco 
+	print "insipid: " ua_insipid
+	print "Hotsip: " ua_hotsip 
+	print "mxsf: " ua_mxsf 
+	print "GrandStream: " ua_grandstream
+	print "Tellme: "ua_tellme 
+	print "PocketSipM: " ua_pocketsipm 
+	print "eStara: " ua_estara 
+	print "Vovida: " ua_vovida 
+	print "jSIP: " ua_jsip 
+	print "Nortel: " ua_nortel 
+	print "Polycom: " ua_polycom
+	print "Leader: " ua_leader 
+	print "csco: " ua_csco 
+	print "Nebula: " ua_nebula
+	print "MagicPPC: " ua_magicppc 
+	print "SCS: " ua_scs 
+	print "SJPhone: " ua_sjphone 
+	print "KPhone: " ua_kphone
 	print "Yamaha: " ua_yamaha 
 	print "tkcPhone: " ua_tkc
 	print "EdgeAccess: " ua_edgeaccess
@@ -762,6 +877,17 @@ END {
 	print "D-link: " ua_dlink
 	print "gphone: " ua_gphone
 	print "X-lite: " ua_xlite
+	print "grandstream: " ua_gs
+	print "vegastream: " ua_vega
+	print "Ahead SIPPS: " ua_sipps
+	print "IBM user agent: " ua_ibm
+	print "i3micro: " ua_i3micro
+	print "ACT: " ua_act
+	print "X-pro: " ua_xpro
+	print "Hearme: " ua_hearme
+	print "DrayTek: " ua_draytek
+	print "ST: " ua_st
+	print "DTA: " ua_dta
 	print "UFO: " ua_xx
 
 	print "## Servers"
@@ -778,6 +904,10 @@ END {
 	print "StarSIP: " server_starsip
 	print "ipDialog: " server_ipdialog
 	print "eDial: " server_edial
+	print "FWD: " server_fwd
+	print "MA: " server_ma
+	print "Columbia: " server_columbia
+	print "PartySip: " server_partysip
 	print "UFO: " server_xx
 }
 '

+ 32 - 43
scripts/ser_mysql.sh

@@ -140,7 +140,7 @@ EOF
 # read realm
 prompt_realm() 
 {
-	printf "Doamin (realm) for the default user 'admin': "
+	printf "Domain (realm) for the default user 'admin': "
 	read SIP_DOMAIN
 	echo
 }
@@ -229,7 +229,7 @@ INSERT INTO version VALUES ( 'realm', '1');
 INSERT INTO version VALUES ( 'domain', '1');
 INSERT INTO version VALUES ( 'uri', '1');
 INSERT INTO version VALUES ( 'server_monitoring', '1');
-INSERT INTO version VALUES ( 'server_monitoring_ul', '1');
+INSERT INTO version VALUES ( 'server_monitoring_agg', '1');
 
 
 #
@@ -248,6 +248,7 @@ CREATE TABLE acc (
   to_uri varchar(128) NOT NULL default '',
   sip_callid varchar(128) NOT NULL default '',
   $USERCOL varchar(64) NOT NULL default '',
+  domain varchar(100) NOT NULL default '',
   fromtag varchar(128) NOT NULL default '',
   totag varchar(128) NOT NULL default '',
   time datetime NOT NULL default '0000-00-00 00:00:00',
@@ -301,6 +302,7 @@ CREATE TABLE aliases (
 CREATE TABLE event (
   id int(10) unsigned NOT NULL auto_increment,
   $USERCOL varchar(50) NOT NULL default '',
+  domain varchar(100) NOT NULL default '',
   uri varchar(255) NOT NULL default '',
   description varchar(255) NOT NULL default '',
   PRIMARY KEY (id)
@@ -365,6 +367,7 @@ CREATE TABLE missed_calls (
   to_uri varchar(128) NOT NULL default '',
   sip_callid varchar(128) NOT NULL default '',
   $USERCOL varchar(64) NOT NULL default '',
+  domain varchar(100) NOT NULL default '',
   fromtag varchar(128) NOT NULL default '',
   totag varchar(128) NOT NULL default '',
   time datetime NOT NULL default '0000-00-00 00:00:00',
@@ -383,6 +386,7 @@ CREATE TABLE missed_calls (
 CREATE TABLE pending (
   phplib_id varchar(32) NOT NULL default '',
   $USERCOL varchar(100) NOT NULL default '',
+  domain varchar(100) NOT NULL default '',
   password varchar(25) NOT NULL default '',
   first_name varchar(25) NOT NULL default '',
   last_name varchar(45) NOT NULL default '',
@@ -395,7 +399,6 @@ CREATE TABLE pending (
   sendnotification varchar(50) NOT NULL default '',
   greeting varchar(50) NOT NULL default '',
   ha1 varchar(128) NOT NULL default '',
-  domain varchar(128) NOT NULL default '',
   ha1b varchar(128) NOT NULL default '',
   perms varchar(32) default NULL,
   allow_find char(1) NOT NULL default '0',
@@ -416,6 +419,7 @@ CREATE TABLE pending (
 CREATE TABLE phonebook (
   id int(10) unsigned NOT NULL auto_increment,
   $USERCOL varchar(50) NOT NULL default '',
+  domain varchar(100) NOT NULL default '',
   fname varchar(32) NOT NULL default '',
   lname varchar(32) NOT NULL default '',
   sip_uri varchar(128) NOT NULL default '',
@@ -447,6 +451,7 @@ CREATE TABLE reserved (
 CREATE TABLE subscriber (
   phplib_id varchar(32) NOT NULL default '',
   $USERCOL varchar(100) NOT NULL default '',
+  domain varchar(100) NOT NULL default '',
   password varchar(25) NOT NULL default '',
   first_name varchar(25) NOT NULL default '',
   last_name varchar(45) NOT NULL default '',
@@ -459,7 +464,6 @@ CREATE TABLE subscriber (
   sendnotification varchar(50) NOT NULL default '',
   greeting varchar(50) NOT NULL default '',
   ha1 varchar(128) NOT NULL default '',
-  domain varchar(128) NOT NULL default '',
   ha1b varchar(128) NOT NULL default '',
   perms varchar(32) default NULL,
   allow_find char(1) NOT NULL default '0',
@@ -476,6 +480,7 @@ CREATE TABLE config (
    attribute varchar(32) NOT NULL,
    value varchar(128) NOT NULL,
    $USERCOL varchar(100) NOT NULL default '',
+   domain varchar(100) NOT NULL default '',
    modified timestamp(14)
 ) $TABLE_TYPE;
 
@@ -520,39 +525,14 @@ CREATE TABLE uri (
 #
 
 
+DROP TABLE IF EXISTS server_monitoring;
 CREATE TABLE server_monitoring (
   time datetime NOT NULL default '0000-00-00 00:00:00',
-  ts_current int(10) unsigned default NULL,
-  ts_waiting int(10) unsigned default NULL,
-  ts_total int(10) unsigned default NULL,
-  ts_total_local int(10) unsigned default NULL,
-  ts_replied int(10) unsigned default NULL,
-  ts_6xx int(10) unsigned default NULL,
-  ts_5xx int(10) unsigned default NULL,
-  ts_4xx int(10) unsigned default NULL,
-  ts_3xx int(10) unsigned default NULL,
-  ts_2xx int(10) unsigned default NULL,
-  sl_200 int(10) unsigned default NULL,
-  sl_202 int(10) unsigned default NULL,
-  sl_2xx int(10) unsigned default NULL,
-  sl_300 int(10) unsigned default NULL,
-  sl_301 int(10) unsigned default NULL,
-  sl_302 int(10) unsigned default NULL,
-  sl_3xx int(10) unsigned default NULL,
-  sl_400 int(10) unsigned default NULL,
-  sl_401 int(10) unsigned default NULL,
-  sl_403 int(10) unsigned default NULL,
-  sl_404 int(10) unsigned default NULL,
-  sl_407 int(10) unsigned default NULL,
-  sl_408 int(10) unsigned default NULL,
-  sl_483 int(10) unsigned default NULL,
-  sl_4xx int(10) unsigned default NULL,
-  sl_500 int(10) unsigned default NULL,
-  sl_5xx int(10) unsigned default NULL,
-  sl_6xx int(10) unsigned default NULL,
-  sl_xxx int(10) unsigned default NULL,
-  sl_failures int(10) unsigned default NULL,
-  PRIMARY KEY  (time)
+  id int(10) unsigned NOT NULL default '0',
+  param varchar(32) NOT NULL default '',
+  value int(10) NOT NULL default '0',
+  increment int(10) NOT NULL default '0',
+  PRIMARY KEY  (id,param)
 ) $TABLE_TYPE;
 
 
@@ -565,19 +545,28 @@ CREATE TABLE preferences (
 ) $TABLE_TYPE;
 
 #
-# Table structure for table 'server_monitoring_ul'
+# Table structure for table 'server_monitoring_agg'
 #
 
 
-CREATE TABLE server_monitoring_ul (
-  time datetime NOT NULL default '0000-00-00 00:00:00',
-  domain varchar(64) NOT NULL default '',
-  registered int(10) unsigned default NULL,
-  expired int(10) unsigned default NULL,
-  PRIMARY KEY  (domain,time)
+DROP TABLE IF EXISTS server_monitoring_agg;
+CREATE TABLE server_monitoring_agg (
+  param varchar(32) NOT NULL default '',
+  s_value int(10) NOT NULL default '0',
+  s_increment int(10) NOT NULL default '0',
+  last_aggregated_increment int(10) NOT NULL default '0',
+  av float NOT NULL default '0',
+  mv int(10) NOT NULL default '0',
+  ad float NOT NULL default '0',
+  lv int(10) NOT NULL default '0',
+  min_val int(10) NOT NULL default '0',
+  max_val int(10) NOT NULL default '0',
+  min_inc int(10) NOT NULL default '0',
+  max_inc int(10) NOT NULL default '0',
+  lastupdate datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY  (param)
 ) $TABLE_TYPE;
 
-
 # add an admin user "admin" with password==heslo, 
 # so that one can try it out on quick start
 

+ 563 - 0
scripts/serconf.sh

@@ -0,0 +1,563 @@
+#!/bin/sh
+#
+# $Id$
+#
+# SER configuration script
+#
+# disclaimer: extremely simplistic and experimental
+# useful only for people who know what they are doing
+# and want to save some typing
+#
+# call it to generate a basic script -- you have to
+# carry out any subsequent changes manually
+#
+
+# ------------------- Variables ------------------------
+
+# prompted variables
+# SER_DOMAIN -- name of served domain, e.g., foo.bar.com
+# SER_GWIP -- IP address of PSTN gateway, e.g. 10.0.0.1
+
+# parameters that are typically not changed
+SER_SQL_URI="sql://ser:heslo@localhost/ser"
+# set LIB_PATH if all modules are installed in a single
+# directory; otherwise, modules are sought in 'modules'
+# subdirectories
+#SER_LIB_PATH="/usr/local/lib/ser/modules"
+
+
+# --------------------- functions ---------------------------
+function go_to_pstn()
+{
+	if [ -n "$SER_GWIP" ] ; then 
+		cat << EOGOTOPSTN
+	# now check if it's about PSTN destinations through our gateway;
+	# note that 8.... is exempted for numerical non-gw destinations
+	if (uri=~"sip:\+?[0-79][0-9]*@.*") {
+		route(3);
+		break;
+	}; 
+EOGOTOPSTN
+	fi
+}
+
+
+function addr2re()
+{
+	echo $1 |  sed -ne "s/\./\\\./gp"
+}
+
+function gw_check()
+{
+	if [ -n "$SER_GWIP" ] ; then 
+		cat << EOGWTEST
+		if (uri=~"sip:[+0-9]+@$SER_GWIP_RE") {
+			# it is gateway -- proceed to ACLs
+			route(3);
+			break;
+		};
+EOGWTEST
+	fi
+}
+
+function mine_check()
+{
+	printf "uri=~\"[@:](sip[\.)?$SER_DOMAIN_TEST_RE([;:].*)*\" $SER_GW_TEST_RE"
+}
+
+function gw_m_check()
+{
+	if [ -n "$SER_GWIP" ] ; then 
+		cat << EOMCHECK
+		if (search("^(Contact|m): .*$SER_GWIP_RE")) {
+			log(1, "LOG: alert: protected contacts\n");
+			sl_send_reply("476", "No Server Address in Contacts Allowed" );
+			break;
+		};
+EOMCHECK
+	fi
+}
+
+function help()
+{
+	cat << EOHELP
+Numbering plan is as follows:
+- numbers beginning with 8 are considered aliases
+- numbers beginning with + are considered ENUM destinations
+EOHELP
+	if [ -n "$SER_GWIP" ] ; then
+		cat << EOHELP2
+- all other numbers are considered PSTN destinations
+  ... to dial PSTN, a user must have 'int' privilege
+EOHELP2
+	else
+		echo "- all other numbers are considered usernames"
+	fi
+}
+
+function usage()
+{
+	echo "Usage: $0 <domain_name> [<ip_address_of_gateway>]" \
+		'> <config_file>' > /dev/stderr
+	exit 1
+}
+
+function load_mod()
+{
+	if [ -n "$SER_LIB_PATH" ] ; then
+		echo "loadmodule \"$SER_LIB_PATH/$1.so\""
+	else
+		echo "loadmodule \"modules/$1/$1.so\""
+	fi
+}
+
+# ----------------------- user-parameter check ---------------
+# SER_DOMAIN -- name of served domain, e.g., foo.bar.com
+# SER_GWIP -- IP address of PSTN gateway, e.g. 10.0.0.1
+
+if [ $# -gt 0 ] ; then
+	SER_DOMAIN="$1"
+	shift
+	if [ $# -gt 0 ] ; then
+		SER_GWIP="$1"
+		shift
+	fi
+	if [ $# -gt 0 ] ; then
+		usage
+	fi
+else
+	usage
+fi
+
+# ---------------------- initialization -------------------------
+
+# autodetection parameters
+SER_IP=`/sbin/ifconfig eth0 | 
+	sed -ne 's/\( \)*\(inet addr:\)\([0-9\.]*\).*/\3/gp'`
+
+# construction of regular expressions
+SER_IP_RE=`addr2re $SER_IP`
+SER_DOMAIN_RE=`addr2re $SER_DOMAIN`
+
+# tests
+# - is this for my domain
+SER_DOMAIN_TEST_RE=`printf "($SER_DOMAIN_RE|$SER_IP_RE)"`
+# - is this for my gateway ?
+if [ -n "$SER_GWIP" ] ; then
+	SER_GWIP_RE=`addr2re $SER_GWIP`
+	SER_GW_TEST_RE=`printf "| uri=~\"@$SER_GWIP_RE([;:].*)*\""`
+fi
+
+SER_REGISTRAR="registrar@$SER_DOMAIN"
+
+# ---------------------- verficiation --------------------------
+set | grep ^SER_ > /dev/stderr
+echo > /dev/stderr
+echo "IS EVERYTHING OK ???? (press ^C to interrupt)" > /dev/stderr
+read
+
+
+# --------------------- dump it here -------------------------
+
+cat << EOF
+
+#
+# \$Id$
+#
+# autogenerated SER configuration 
+#
+# user: `id`
+# system: `uname -a`
+# date: `date`
+#
+
+# ----------- global configuration parameters ------------------------
+
+debug=3
+fork=yes
+port=5060
+log_stderror=no
+memlog=5
+
+mhomed=yes
+
+fifo="/tmp/ser_fifo"
+
+alias=$SER_DOMAIN
+
+# uncomment to override config values for test 
+/* 
+debug=3             # debug level (cmd line: -ddd)
+fork=no
+port=5068
+log_stderror=yes	# (cmd line: -E)
+fifo="/tmp/ser_fifox"
+ */
+
+
+check_via=no		# (cmd. line: -v)
+dns=no              # (cmd. line: -r)
+rev_dns=no          # (cmd. line: -R)
+children=16
+# if changing fifo mode to a more restrictive value, put
+# decimal value in there, e.g. dec(rw|rw|rw)=dec(666)=438
+#fifo_mode=438
+
+# ------------------ module loading ----------------------------------
+
+`load_mod tm`
+`load_mod sl`
+`load_mod acc`
+`load_mod rr`
+`load_mod maxfwd`
+`load_mod mysql`
+`load_mod usrloc`
+`load_mod registrar`
+`load_mod auth`
+`load_mod auth_db`
+`load_mod textops`
+`load_mod uri`
+`load_mod group`
+`load_mod msilo`
+`load_mod enum`
+
+
+
+# ----------------- setting module-specific parameters ---------------
+
+# all DB urls here
+modparam("usrloc|acc|auth_db|group|msilo|uri", "db_url",
+	"$SER_SQL_URI")
+
+# -- usrloc params --
+/* 0 -- dont use mysql, 1 -- write_through, 2--write_back */
+modparam("usrloc", "db_mode",   2)
+modparam("usrloc", "timer_interval", 10)
+
+# -- auth params --
+
+modparam("auth_db", "calculate_ha1", yes)
+#modparam("auth_db", "user_column",   "user_id")
+modparam("auth_db", "password_column",   "password")
+modparam("auth", "nonce_expire",  300)
+
+# -- rr params --
+# add value to ;lr param to make some broken UAs happy
+modparam("rr", "enable_full_lr", 1)
+
+# -- acc params --
+# that is the flag for which we will account -- don't forget to
+modparam("acc", "db_flag", 1 )
+modparam("acc", "db_missed_flag", 3 )
+
+# -- tm params --
+modparam("tm", "fr_timer", 20 )
+modparam("tm", "fr_inv_timer", 90 )
+modparam("tm", "wt_timer", 20 )
+
+# -- msilo params
+modparam("msilo", "registrar", "sip:$SER_REGISTRAR")
+
+# -- enum params --
+#
+modparam("enum", "domain_suffix", "e164.arpa.")
+
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
+
+route{
+
+	/* ********* ROUTINE CHECKS  ********************************** */
+
+	# filter too old messages
+	if (!mf_process_maxfwd_header("10")) {
+		log("LOG: Too many hops\n");
+		sl_send_reply("483","Alas Too Many Hops");
+		break;
+	};
+	if (len_gt( max_len )) {
+		sl_send_reply("513", "Message too large sorry");
+		break;
+	};
+
+
+	# Make sure that requests dont advertise addresses 
+	# from private IP space (RFC1918) in Contact HF
+	# (note: does not match with folded lines)
+	if (search("^(Contact|m): .*@(192\.168\.|10\.|172\.16)")) {
+		# allow RR-ed requests, as these may indicate that
+		# a NAT-enabled proxy takes care of it; unless it is
+		# a REGISTER
+		if ((method=="REGISTER" || ! search("^Record-Route:")) 
+					&& !( src_ip==192.168.0.0/16 ||
+						src_ip==10.0.0.0/8 || src_ip==172.16.0.0/12 )) {
+			log("LOG: Someone trying to register from private IP again\n");
+			sl_send_reply("479", "We dont accept private IP contacts" );
+			break;
+		};
+	};
+
+	# anti-spam -- if somene claims to belong to our domain in From,
+	# challenge him (skip REGISTERs -- we will chalenge them later)
+	if (search("(From|F):.*$SER_DOMAIN_TEST_RE")) {
+		# invites forwarded to other domains, like FWD may cause subsequent 
+		# request to come from there but have iptel in From -> verify
+		# only INVITEs (ignore FIFO/UAC's requests, i.e. src_ip==myself)
+		if (method=="INVITE" &  !(src_ip==$SER_IP)) {
+			if  (!(proxy_authorize(	"$SER_DOMAIN" /* realm */,
+					"subscriber" /* table name */ ))) {
+				proxy_challenge("$SER_DOMAIN" /* realm */, "0" /* no-qop */);
+				break;
+			};
+			# to maintain outside credibility of our proxy, we enforce
+			# username in From to equal digest username; user with
+			# "john.doe" id could advertise "bill.gates" in From otherwise;
+			if (!check_from()) {
+				log("LOG: From Cheating attempt in INVITE\n");
+				sl_send_reply("403", "That is ugly -- use From=id next time (OB)");
+				break;
+			};
+            		# we better don't consume credentials -- some requests may be
+            		# spiraled through our server (sfo@iptel->7141@iptel) and the
+            		# subsequent iteration may challenge too, for example because of
+            		# iptel claim in From; UACs then give up because they
+        		# already submitted credentials for the given realm
+			#consume_credentials();
+		}; # INVITEs claiming to come from our domain
+	} else if (method=="INVITE" && !(uri=~"[@:\.]$SER_DOMAIN_TEST_RE([;:].*)*" 
+			# ... and we serve our gateway too if present
+			$SER_GW_TEST_RE )) {
+		#the INVITE neither claims to come from our domain nor is it targeted to it
+		# -> junk it
+		sl_send_reply("403", "No relaying");
+		break;
+	};
+
+
+	/* ********* RR ********************************** */
+	# to be safe, record route everything; UAs may use different
+	# transport protocols and need to have SER in path
+	record_route();
+	# if route forces us to forward to some explicit destination,
+	# do so; check however first that a cheater didn't preload 
+	# a gateway destination to bypass PSTN ACLs
+
+	if (loose_route()) {
+		`gw_check`
+		# route HF determined next hop; forward there
+		append_hf("P-hint: rr-enforced\r\n");
+		t_relay();
+		break;
+	};
+
+
+	/*  *********  check for requests targeted out of our domain... ******* */
+	# sign of our domain: there is '@' (username) or  : (nothing) in 
+	# front of our domain name	; ('.' is not there -- we handle all
+	# xxx.iptel.org as outbound hosts);if none of these cases matches, 
+	# proceed with processing of outbound requests in route[2]
+	if (!(`mine_check`)) {
+		route(2);
+		break;
+	};
+
+
+	/* ************ requests for our domain ********** */
+
+
+	/* now, the request is for sure for our domain */
+
+
+	# registers always MUST be authenticated to
+	# avoid stealing incoming calls	
+	if (method=="REGISTER") {
+
+		# Make sure that user's dont register infinite loops
+		# (note: does not match with folded lines)
+		if (search("^(Contact|m): .*@$SER_DOMAIN_TEST_RE")) {
+			log(1, "LOG: alert: someone trying to set aor==contact\n");
+			sl_send_reply("476", "No Server Address in Contacts Allowed" );
+			break;
+		};
+		`gw_m_check`
+
+		if (!www_authorize(	"$SER_DOMAIN" /* realm */, 
+			 				"subscriber" /* table name */ )) {
+			# challenge if none or invalid credentials
+ 			www_challenge(	"$SER_DOMAIN" /* realm */, 
+							"0" /* no qop -- some phones can't deal with it */);
+			break;
+		};
+
+		# prohibit attempts to grab someone else's To address 
+		# using  valid credentials; 
+
+		if (!check_to()) {
+			log("LOG: To Cheating attempt\n");
+			sl_send_reply("403", "That is ugly -- use To=id in REGISTERs");
+			break;
+		};
+		# it is an authenticated request, update Contact database now
+		if (!save("location")) {
+			sl_reply_error();
+		};
+		m_dump();
+		break;
+	};
+
+	# some UACs might be fooled by Contacts our UACs generate to make MSN 
+	# happy (web-im, e.g.) -- tell its urneachable
+	if (uri=~"sip:daemon@" ) {
+		sl_send_reply("410", "daemon is gone");
+		break;
+	};
+
+	# is this an ENUM destination (leading +?)? give it a try, if the lookup
+	# doesn't change URI, just continue
+	if (uri=~"sip:\+[0-9]+@") {
+		if (!enum_query("voice")) { # if parameter empty, it defaults to "e2u+sip"
+			enum_query(""); # E2U+sip
+		};
+	} else {
+		# aliases  (take precedences over PSTN number; provisioning interface
+		# is set up to assinge aliases beginning with 8)
+		lookup("aliases");
+	};
+
+
+	# check again, if it is still for our domain after aliases are resolved
+	if (!(`mine_check`)) {
+		route(5);
+		break;
+	};
+
+	`go_to_pstn`
+
+	# native SIP destinations are handled using our USRLOC DB
+	if (!lookup("location")) {
+		# handle user which was not found ...
+		route(4);
+		break;
+	};
+	# check whether some inventive user has uploaded  gateway 
+	# contacts to UsrLoc to bypass our authorization logic
+	`gw_check`
+
+	/* ... and also report on missed calls ... */
+	setflag(3);
+
+	# we now know we may, we know where, let it go out now!
+	append_hf("P-hint: USRLOC\r\n");
+	if (!t_relay()) {
+		sl_reply_error();
+		break;
+	};
+}
+#------------------- OUTBOUND ----------------------------------------
+
+# routing logic for outbound requests targeted out of our domain
+# (keep in mind messages to our users can end up here too: for example,
+#  an INVITE may be UsrLoc-ed, then the other party uses outbound
+#  proxy with r-uri=the usr_loced addredd (typically IP))
+route[2] {
+	append_hf("P-hint: OUTBOUND\r\n");
+	t_relay();
+}
+
+#------- ALIASED OUTBOUND --------------------------------------------
+
+# routing logic for inbound requests aliased outbound; unlike
+# with real outbound requests we do not force authentication
+# as these calls are server by our server and we do not want
+# to disqualify unathenticated request originatiors from other
+# domains
+route[5] {
+	append_hf("P-hint: ALIASED-OUTBOUND\r\n");
+	t_relay();
+}
+
+#----------------- PSTN ----------------------------------------------
+
+# logic for calls to the PSTN
+route[3] {
+	# turn accounting on
+	setflag(1);
+
+	/* require all who call PSTN to be members of the "int" group;
+	   apply ACLs only to INVITEs -- we don't need to protect other requests, as they
+	   don't imply charges; also it could cause troubles when a call comes in via PSTN
+	   and goes to a party that can't authenticate (voicemail, other domain) -- BYEs would
+	   fail then; exempt Cisco gateway from authentication by IP address -- it does not
+	   support digest
+	*/
+	if (method=="INVITE" && (!src_ip==$SER_GWIP)) {
+		if (!proxy_authorize(	"$SER_DOMAIN" /* realm */,
+						"subscriber" /* table name */))  {
+			proxy_challenge( "$SER_DOMAIN" /* realm */, "0" /* no qop */ );
+			break;
+		};
+		# let's check from=id ... avoids accounting confusion
+		if (method=="INVITE" & !check_from()) {
+			log("LOG: From Cheating attempt\n");
+			sl_send_reply("403", "That is ugly -- use From=id next time (gw)");
+			break;
+		};
+
+		if(!is_user_in("credentials", "int")) {
+			sl_send_reply("403", "NO PSTN Privileges...");
+			break;
+		};
+		consume_credentials();
+
+	}; # INVITE to authorized PSTN
+
+	# if you have passed through all the checks, let your call go to GW!
+	rewritehostport("$SER_GWIP:5060");
+
+	# snom conditioner
+	if (method=="INVITE" && search("User-Agent: snom")) {
+		replace("100rel, ", "");
+	};
+
+	append_hf("P-hint: GATEWAY\r\n");
+	# use UDP to guarantee well-known sender port (TCP ephemeral)
+	t_relay_to_udp("$SER_GWIP","5060");
+}
+
+
+
+/* *********** handling of unavailable user ******************* */
+
+route[4] {
+/**/
+	# message store 
+	if (method=="MESSAGE") {
+		t_newtran();
+		if (m_store("0")) {
+			t_reply("202", "Accepted for Later Delivery");
+		} else {
+			t_reply("503", "Service Unavailable");
+		};
+		break;
+	};
+/**/
+	# non-Voip -- just send "off-line"
+	if (!(method=="INVITE" || method=="ACK" || method=="CANCEL")) {
+		sl_send_reply("404", "Not Found");
+		break;
+	};
+	# voicemail subscribers ...
+	t_newtran();
+	t_reply("404", "Not Found");
+	# we account missed incoming calls; previous statteful processing
+	# guarantees that retransmissions are not accounted
+	if (method=="INVITE") {
+		acc_db_request("404 missed call", "missed_calls");
+	};
+}
+
+EOF
+
+help > /dev/stderr