[Asterisk-Users] Speaking of DS3s....

Michael Shuler mike at bwsys.net
Thu Nov 18 22:45:46 MST 2004


SER is a stateless and/or stateless proxy.  SER by itself it not very useful
but SER teamed with Asterisk is how you make Asterisk scale.  SER normally
has nothing to do with the RTP stream.  Remember in the SIP world there are
really 2 parts, 1 is the SIP messages and 2 is the RTP "voice" stream.  The
SIP messages tell the 2 voice gateways (an ATA and a TNT for example) what
codec, IP, port, etc. to pass the "voice" traffic on.


SER can be setup quite easily (after you get used to its config file) to
handle simple STATELESS SIP message proxying.  Asterisk is a stateful proxy
and is fully aware of the state of the call.  Asterisk is also considered to
be a feature server, IVR, VM, etc. server.  But what Asterisk is most
certainly not is a stateless proxy server.  In the IP world you can relate
the job of a stateless proxy server to a IP router.  It knows what's
attached to it and what path to send it.  It has no idea what is in what it
is sending but it knows how to get it there.

At first this makes SER look quite inferior to Asterisk, but in reality they
are very complimentary.

So below is some of my ser.cfg file that will give you an idea of how to
make it work.  I originally wasn't going to disclose this but I've gotten
about 100 emails on how to do this so I figure since the mailing lists
helped me out when I first got started I might as well return the favor.
IP's and stuff have been changed so substitute with your own.  Also, I do a
lot of DB table combining to make life easier to SER and Asterisk share the
same auth tables.  If you want them I can do a dump of the struct of my
whole Asterisk DB.  Keep in mind its built for working with the res_data
patch and SER.  Plain old Asterisk wont do any of this without the patch.
Also, keep in mind I don't use the standard paths for install so my config
points to non-standard places.  I also took out the SER register replication
stuff because it made it way to confusing for your first time looking at a
live config file.

AND, one final note about NAT.  SER handles NAT for the SIP messages but
Asterisk handles NAT for the RTP packets.  It's a very odd setup but it will
eliminate a point of failure if you tried to have SER run its mediaproxy or
RTP portion of its nathelper module.  After all Asterisk insists on having
the RTP stream go through it anyway. 

I have no idea what res_config is but res_data does do it in real time.

----------------------------------------

Michael Shuler



Ser.cfg:

debug=3         # debug level (cmd line: -dddddddddd)
fork=yes
log_stderror=no # (cmd line: -E)

# Uncomment these lines to enter debugging mode 
# debug=7
# fork=no
# log_stderror=yes

listen=123.123.123.123
sip_warning=no

alias=ser
alias=ser.mycompany.com
alias=mycompany.com

advertised_address=123.123.123.123

reply_to_via=no
check_via=no    # (cmd. line: -v)
dns=no           # (cmd. line: -r)
rev_dns=no      # (cmd. line: -R)
port=5060
children=4
fifo="/tmp/ser_fifo"

# ------------------ module loading ----------------------------------

# Uncomment this if you want to use SQL database
loadmodule "/software/ser/ser/lib/ser/modules/mysql.so"

loadmodule "/software/ser/ser/lib/ser/modules/sl.so"
loadmodule "/software/ser/ser/lib/ser/modules/tm.so"
loadmodule "/software/ser/ser/lib/ser/modules/rr.so"
loadmodule "/software/ser/ser/lib/ser/modules/maxfwd.so"
loadmodule "/software/ser/ser/lib/ser/modules/usrloc.so"
loadmodule "/software/ser/ser/lib/ser/modules/registrar.so"
loadmodule "/software/ser/ser/lib/ser/modules/nathelper.so"
loadmodule "/software/ser/ser/lib/ser/modules/textops.so"
loadmodule "/software/ser/ser/lib/ser/modules/xlog.so"

# Uncomment this if you want digest authentication
# mysql.so must be loaded !
loadmodule "/software/ser/ser/lib/ser/modules/auth.so"
loadmodule "/software/ser/ser/lib/ser/modules/auth_db.so"

# ----------------- setting module-specific parameters ---------------

# -- usrloc params --
# Flush every 60 sec
modparam("usrloc", "db_mode", 1)
modparam("usrloc", "db_url",
"sql://Asterisk:Asterisk@mysql.mycompany.com/Asterisk")

# -- auth params --
modparam("auth_db", "db_url",
"sql://Asterisk:Asterisk@mysql.mycompany.com/Asterisk")
modparam("auth_db", "user_column", "username")
modparam("auth_db", "domain_column", "domain")
modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "password_column", "password")

# -- replication auth param --
modparam("auth", "secret", "mysecret")

# -- rr params --
# add value to ;lr param to make some broken UAs happy
modparam("rr", "enable_full_lr", 1)

# -------------------------  request routing logic -------------------

# main routing logic

route{

        # initial sanity checks -- messages with
        # max_forwards==0, or excessively long requests
        if (!mf_process_maxfwd_header("10")) {
                sl_send_reply("483","Too Many Hops");
                break;
        };
        if ( msg:len > max_len ) {
                sl_send_reply("513", "Message too big");
                break;
        };

        # if(method != "REGISTER")
        # {
        #       xlog("L_INFO", "Got a %rm (URI = %ru) from %is");
        # };

        # By default we are already responding to the learned IP:PORT that
the message came from.  
        # This will properly fix the contact header.  Asterisk will fix the
SDP (actually it learns it).
        
        force_rport();
        fix_nated_contact();

        #
----------------------------------------------------------------------------
--------------------

        # if the request is for other domain use UsrLoc
        # (in case, it does not work, use the following command
        # with proper names and addresses in it)
        if(uri == myself || src_ip == ser.mycompany.com)
        { 
                if(method == "REGISTER") 
                {
                        # Make sure they are a valid user on our proxy
                        if(!www_authorize("mycompany.com", "sipfriends")) 
                        {
                                # xlog("L_INFO", "Req Auth For %ct, URI =
%ru");
                                www_challenge("mycompany.com", "1");
                                break;
                        };

                        # xlog("L_INFO", "Registered Contact %ct,  URI =
%ru");
                        save("location");

                        break;
                };
        };


        #
----------------------------------------------------------------------------
--------------------

        # we record-route all messages -- to make sure that
        # subsequent messages will go through our proxy; that's
        # particularly good if upstream and downstream entities
        # use different transport protocol
        record_route();  
	  # This will make the return path the VIRTUAL IP on a L4 switch
instead of our REAL IP
        # record_route_preset("111.222.333.444:5060");

        #
----------------------------------------------------------------------------
--------------------
        
        # loose-route processing
        if(loose_route())
        {
                xlog("L_INFO", "loose_route(): Looking up %rm URI %ru from
%is");
                lookup("location");
                xlog("L_INFO", "loose_route(): t_relay() %rm to URI %ru");
                t_relay();
                break;
        };


        #
----------------------------------------------------------------------------
--------------------

        # We only need to do load balancing on the INVITE.  
        # After the dest IP has been put in the message the servers will
follow it on their own.
        if(method == "INVITE")
        {

                # If it came from Asterisk send it to a TNT box for final
routing if it can't be looked up
                # As of now its ast0 and ast1 which are 222.222.222.222 and
333.333.333.333 which fall within this subnet
                if(src_ip == 222.222.222.222 || src_ip == 333.333.333.333)
                {
                        xlog("L_INFO", "%rm came from Asterisk server %is,
URI = %ru");
                
                        # native SIP destinations are handled using our
USRLOC DB
                        if(lookup("location"))
                        {
                                # Found a match, this is going to a VoIP
phone
                                xlog("L_INFO", "Sending %rm (URI = %ru) to
Contact (%ct)");
                        }
                        else
                        {
                                # Lookup failed, assume that this is a phone
number URL until I setup pattern matching
                                # Send to the TNT
                                xlog("L_INFO", "Sending URI (%ru) to TNT");
                                rewritehostport("tnt.mycompany.com:5060");

                        };
                }


                # NOTE: I could have combine the following "else if" and
"else" but I wanted to seperate them for debug purposes
                # If it came from a TNT send it to an Asterisk box for final
routing
                # As of now TNT is 444.444.444.444 which falls within this
subnet
                else if(src_ip == 444.444.444.444)
                {
                        xlog("L_INFO", "%rm came from TNT (%is), sending to
Asterisk (URI = %ru)");
                        rewritehostport("ast.mycompany.com:5060");   
				# I cheated here because I made
ast.mycompany.com a DNS round robing with a 5 sec experation.  It's not a
load checking load balancer but its REALLY close.    
                }
             
                # Assume it came from one of our VoIP phones, all routing is
done by Asterisk
                else 
                {
                        xlog("L_INFO", "%rm came from a VoIP phone (%is),
attempting to authorize %fu");

                        # Make sure they are a valid user on our proxy
                        if (!www_authorize("mycompany.com", "sipfriends"))
                        {
                                www_challenge("mycompany.com", "0");
                                xlog("L_INFO", "Failed to authorize %fu
(%is)");
                                break;
                        };

                        # Found a match, this is going to a VoIP phone
                        xlog("L_INFO", "Auth OK, sending URI %ru to Asterisk
for routing");
                        rewritehostport("ast.mycompany.com:5060");        
                };

                xlog("L_INFO", "INVITE New URI = %ru, t_relay()ing now");
                t_relay();
                # forward(uri:host, uri:port);
                break;
        };

        #
----------------------------------------------------------------------------
--------------------


        # forward to current uri now; use stateful forwarding; that
        # works reliably even if we forward from TCP to UDP
        lookup("location");
        xlog("L_INFO", "Default t_relay() (method = %rm, URI = %ru, >From =
%is)");
        if(!t_relay()) 
        {
                xlog("L_INFO", "Failed sending requesting %rm URI (%ru)");
                sl_reply_error();
        };
}

































> -----Original Message-----
> From: asterisk-users-bounces at lists.digium.com 
> [mailto:asterisk-users-bounces at lists.digium.com] On Behalf Of 
> Tracy R Reed
> Sent: Thursday, November 18, 2004 7:08 PM
> To: Asterisk Users Mailing List - Non-Commercial Discussion
> Subject: Re: [Asterisk-Users] Speaking of DS3s....
> 
> 
> On Thu, Nov 18, 2004 at 04:30:24PM -0600, Michael Shuler spake thusly:
> > the VoIP devices and to the media gateways.  The SER 
> machines don't know
> > what to do with a call they only know to hand it over to 
> Asterisk for
> > routing/CLASS features or whatever you want the call to do. 
>  You then have a
> 
> This is exactly what I am trying to figure out how to set up. 
> I am still a
> bit confused by how the SER box can "hand it over" to the 
> Asterisk box. I
> am pretty fluent in Asterisk by now and have written various code for
> Asterisk so I would like to do my routing and accounting in 
> Asterisk, and
> not SER which I understand requires coding in C to SER's API 
> (correct me
> if I'm wrong here). Since SER is a proxy it does not handle the rtp
> stream, right? But someone recently told me that SER 
> implements comfort
> noise and other nice SIP things that asterisk does not and 
> that you really
> don't want all of the media stream going through asterisk 
> because it won't
> scale. Or maybe the media stream does have to go through 
> asterisk but SER
> just balances the load but that doesn't jive with what I was 
> told about
> comfort noise etc. We also are using asterisk to talk to 
> TNT's and that
> part is working really slick. We have a few DS-3's and I 
> intend to have
> asterisk least cost route traffic to the appropriate TNT etc.
> 
> > Asterisk as media gateways in our setup we use the Lucent 
> TNTs but it
> > accomplishes the same thing but on a much larger scale.  As 
> far as sharing
> > the common configs we use 
> http://svn.asteriskdocs.org/res_data/ to read all
> > of our configs (sip.conf, extensions.conf, etc.) live from 
> a MySQL database.
> > Just apply the patch and go.
> 
> Hmm...what's the difference between res_config and res_data? They both
> seem to put all of the asterisk configs in a database. Does res_config
> just read from the db once and res_data reads in real time?
> 
> -- 
> Tracy Reed    http://copilotcom.com 
> This message is cryptographically signed for your protection.
> Info: http://copilotconsulting.com/sig
> 




More information about the asterisk-users mailing list