Hi Rafael,

You would use the "example code snippet" when you want to decide whether or not to use rtpproxy or mediaproxy based on the fact that both the caller and the callee are behind the same NAT device. Please review the mailing lists as this topic has been discussed many times.

I added some additional comments in regard to the setting of flags 2 and 3 in the posted example at: http://openser.org/dokuwiki/doku.php?id=avp_examples

Generally, I have found that if OpenSER fails to start with an error indicating that the function can't be found, it's time to find the correct module to add.

In response to your last question "etc." I suggest that you review the three web sites: openser.org, iptel.org and onsip.org. The last one has some really great material that explains alot.

Regards,
Norm


Rafael R. GV wrote:
Hi
I am using nathelper/rtpproxy in ser , please see my ser.cfg attached and tell me where do I have to use this code snippet? where did you set flags 2 and 3?, what other modules I need?, etc.

thank you
Rafael
Lima-Peru

On 12/7/05, *Norman Brandinger* <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote:

    Thanks go out to Klaus and Tavis.

    I took the results of this thread and placed it in the docuwiki
    for the
    rest of the user community to use (at least, the rest of the user
    community that reads the docuwiki :)

    http://openser.org/dokuwiki/doku.php?id=avp_examples

    If I made any typos, please feel free to correct them.

    Regards,
    Norm

    _______________________________________________
    Users mailing list
    Users@openser.org <mailto:Users@openser.org>
    http://openser.org/cgi-bin/mailman/listinfo/users
    <http://openser.org/cgi-bin/mailman/listinfo/users>


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

# # If you don't want to enforce RTP proxy for some destinations # then simply use t_relay() instead of route(1) # # Modificado para MYSQL_ACC support
# Handling of Unavailable user and Voicemail redirection (404|408|486)
# # Log Missed Calls (403|404|408|415|484|486|487).
#
# Group checking and PSTN credentials.
#
# 18/07/2005 Prepaid & B2bua support added
# 11/11/2005 LDI a 192.168.2.132 with a2billing
#
# Pendientes !! - Administrar Multi-Dominio para otros Códigos de Area.
# - Completar Logica para tratamiento de llamadas entre # un mismo NAT usando avpops. # # ----------- global configuration parameters ------------------------

#/* Uncomment these lines to enter debugging mode
debug=2
fork=yes
log_stderror=yes
#*/

listen=192.168.2.130
listen=127.0.0.1
port=5060

# hostname matching an alias will satisfy the condition uri==myself".
alias=mydomain.com.pe
alias=127.0.0.1

check_via=no    # (cmd. line: -v)
dns=no          # (cmd. line: -r)
rev_dns=no      # (cmd. line: -R)
children=4
fifo="/tmp/ser_fifo"
fifo_mode=0666  # Fifo permissions can be changes from here.

# sip_warning - Should replies include extensive warnings? # By default yes, it is good for trouble-shooting.
sip_warning=yes

# ------------------ module loading ----------------------------------
loadmodule "/usr/local/lib/ser/modules/domain.so"
loadmodule "/usr/local/lib/ser/modules/avpops.so"
loadmodule "/usr/local/lib/ser/modules/mysql.so"
loadmodule "/usr/local/lib/ser/modules/sl.so"
loadmodule "/usr/local/lib/ser/modules/tm.so"
loadmodule "/usr/local/lib/ser/modules/rr.so"
loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
loadmodule "/usr/local/lib/ser/modules/usrloc.so"
loadmodule "/usr/local/lib/ser/modules/registrar.so"
loadmodule "/usr/local/lib/ser/modules/group.so"
loadmodule "/usr/local/lib/ser/modules/uri.so"
loadmodule "/usr/local/lib/ser/modules/uri_db.so" loadmodule "/usr/local/lib/ser/modules/acc.so"
loadmodule "/usr/local/lib/ser/modules/textops.so"

# digest authentication
loadmodule "/usr/local/lib/ser/modules/auth.so"
loadmodule "/usr/local/lib/ser/modules/auth_db.so"

# !! Nathelper
loadmodule "/usr/local/lib/ser/modules/nathelper.so"

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

modparam("usrloc", "db_mode", 2)

# minimize write back window - default is 60 seconds
modparam("usrloc", "timer_interval", 10)

# database location
modparam("usrloc", "db_url", "mysql://ser:[EMAIL PROTECTED]/ser")

modparam("usrloc", "use_domain", 1)
modparam("auth_db", "use_domain", 1)


modparam("domain", "db_mode", 1)
modparam("domain", "domain_table", "domain")
modparam("domain", "domain_col", "domain")


# ------------- Mysql Accounting parameters
modparam("acc", "log_flag", 1)
modparam("acc", "log_level", 2)
modparam("acc", "db_flag", 1)
modparam("acc", "db_missed_flag", 3)
modparam("acc", "log_missed_flag", 3)
modparam("acc", "db_url", "mysql://seradmin:[EMAIL PROTECTED]/ser")
modparam("acc", "report_ack", 0) # 1 reporta dos starts en acc (para INVITE y 
ACK)
modparam("acc", "failed_transactions", 1) # *all* non-200 transactions marked 
for acc will be logged too.

modparam("acc", "log_fmt", "miocfsputdr")

modparam("tm", "fr_timer", 20 )
modparam("tm", "fr_inv_timer", 40 ) # Timer which hits if no final reply for an 
INVITE
modparam("tm", "wt_timer", 20 )

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

modparam("group", "db_url", "mysql://seradmin:[EMAIL PROTECTED]/ser")
modparam("uri_db", "db_url", "mysql://seradmin:[EMAIL PROTECTED]/ser")

# ------------- registration parameters
modparam("registrar", "nat_flag", 6)
modparam("registrar", "min_expires", 60)
modparam("registrar", "max_expires", 86400)
modparam("registrar", "default_expires", 3600)
modparam("registrar", "desc_time_order", 1)
modparam("registrar", "append_branches", 1)

modparam("registrar", "use_domain", 1)

# !! Nathelper
# modparam("registrar", "nat_flag", 6)
modparam("nathelper", "natping_interval", 30) # Ping interval 30 s
modparam("nathelper", "ping_nated_only", 1)   # Ping only clients behind NAT

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

route {

        log(1, "-------------------------------------------\n");
        log(1, "entering main loop\n");


        # 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;
        };

        # !! Nathelper
        # Special handling for NATed clients; first, NAT test is
        # executed: it looks for via!=received and RFC1918 addresses
        # in Contact (may fail if line-folding is used); also,
        # the received test should, if completed, should check all
        # vias for rpesence of received
        if (nat_uac_test("19")) {
                # 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:")) {
                    log("LOG: Someone trying to register from private IP, 
rewriting\n");

                    # This will work only for user agents that support symmetric
                    # communication. We tested quite many of them and majority 
is
                    # smart enough to be symmetric. In some phones it takes a 
configuration
                    # option. With Cisco 7960, it is called NAT_Enable=Yes, 
with kphone it is
                    # called "symmetric media" and "symmetric signalling".

                    fix_nated_contact(); # Rewrite contact with source IP of 
signalling
                    if (method == "INVITE") {
                        fix_nated_sdp("1"); # Add direction=active to SDP
                    };
                    force_rport(); # Add rport parameter to topmost Via
                    setflag(6);    # Mark as NATed
                };
        };


       # set flag for Radius Accounting:


        if (!method=="OPTIONS") setflag(3);  # SET MISSED_CALLS FLAG FOR ACC

        if (method=="INVITE") {
                log(1, "INVITE MESSAGE RECEIVED - START ACC\n");
                setflag(1); /* set for accounting (the same value as in 
log_flag!) */
        };

        if (method=="BYE") {
                log (1, "BYE  - STOP ACCOUNTING\n");
                setflag(1);
        };

        if (method=="CANCEL") {
                log (1, "CANCEL - STOP ACCOUNTING\n");
                setflag(1);
        };


        # 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

        if (!method=="REGISTER") record_route();

        # subsequent messages withing a dialog should take the
        # path determined by record-routing
# Excluding packets from b2bua (port 5070) if (loose_route() ) {
                log(1," Mark routing logic in request --> rr-enforced \n");
append_hf("P-hint: rr-enforced\r\n"); # t_relay();
                route(1);  # Nathelper!!
                break;
        };

        if (!uri==myself ) {
                log(1," Mark routing logic in request --> outbound\r \n");
append_hf("P-hint: outbound\r\n"); # t_relay();
                route(1); # Nathelper!!
                break;
        };

        if (uri==myself) {

                if (method == "REGISTER") {

                        log(1, "ANALYZING REGISTER REQUEST\n");
                        # to use digest authentication
                        if (is_user_in("Request-URI", "desactivado")) {
                                sl_send_reply("402", "Su cuenta fue 
desactivada");
                                break;
                        };

                        if (!www_authorize("mydomain.com.pe", "subscriber")) {
                                log(1,"       ----- Fails to Register \n");
                                www_challenge("mydomain.com.pe", "0");
                                break;
                        };

# only signed users are allowed if (!check_to()) {
                                log(1, "LOG: Hijack!!!--> unsigned user registration 
attempt\n");
                                sl_send_reply("403", "hijack attempt!!!! Only signed 
users are allowed");
                                break;
                        };
                        log(1,"      Registered!!! \n");
                        if (!save("location")) {
                                sl_reply_error();
                        };
                        break;
                };


        #For *B2bua: First check the source of the call
        #**********************************************
        # If the call comes from the gateways, no authentication is required.
        if (src_ip==192.168.2.145 || src_ip==192.168.2.132 || 
src_ip==192.168.2.131) {
                log(1,"Call from pstn|*, no authentication is required. \n");

# If the call comes from B2BUA, no authentication is required, # The first leg of the call has already been authenticated.
        } else if (src_ip==192.168.2.130 && src_port==5070) {
                log(1,"Call from B2BUA, no authentication is required.  \n");
} else { # We check user credentials
                if ((method == "INVITE" || method== "CANCEL" || method== "BYE" || method== 
"ACK") && (!src_ip==192.168.2.130 && !src_port==5070)){
                log(1, "ANALYZING INVITE||CANCEL REQUESTs\n");
                        if (!proxy_authorize("mydomain.com.pe", "subscriber")) {
                                # log(1,"   ----- Fails to ...proxy_authorize 
\n");
                                proxy_challenge("mydomain.com.pe", "0");
                                break;
                        } else {
                        if (method == "INVITE" && !check_from()) {
sl_send_reply("403", "Only registered users are allowed"); log(1," ----> Only registered users are allowed \n");
                                break;
                        };
                        };

                # Not all the users are PREPAID, so we check the database
                # to see if the call will be routed through B2BUA.
                # If every call is to be routed through B2BUA the "is_user_in"
                # conditional is not required.
                # Do not use b2bua for local calls

                        if (is_user_in("From", "prepaidb") && uri=~"^sip:00") {
                                log(1," ----> Usuario PREPAGO!!! enviando a b2bua... 
\n");
                                rewritehostport("192.168.2.130:5070");
                                t_relay_to_udp("192.168.2.130", "5070");
                                break;
                        };

                };# End of if (method == "INVITE" |...
        };


/* *********** Dial out to Local and PSTN logic ********* */

        # Forward +9n digit requests to gateway Cisco-AS5350 (Celulares):

                if(uri=~"^sip:9" ){
                        log(1," digit expression match - Celulares \n");
                        if (!is_user_in("from", "movlim")) {
                        sl_send_reply("403", "No permission for mobile calls");
                        acc_db_request("403 Forbidden", "missed_calls");
                        break;
}; rewritehostport("192.168.2.145:5060");
                route(1);
                break;
                };


/* ******************************************************************** */
                lookup("aliases");
                # does the user wish redirection on no availability? (i.e., is 
he
                # in the voicemail group?) -- determine it now and store it in
                # flag 4, before we rewrite the flag using UsrLoc

                if (is_user_in("Request-URI", "voicemail")) {
                        log(1, "requested user is in voicemail group \n");
                        setflag(4);
                };

# native SIP destinations are handled using our USRLOC DB:

                # LOOKUP (location)!!!!

                if (!lookup("location")) {
                        log(1,"unable to locate user X ... sending to route(4)! 
\n");
                        # handle user which was not found
                        route(4);
                        break;
                };

            ### Test if UAS are in the same NAT:

                # get the host part of the final uri (IP part) and store it in 
AVP ID 13

                avp_write("$ruri/domain", "i:13");
                if (avp_check("i:13","eq/$src_ip/i")) {
                        log(1, "source IP is the same as destination IP\n");
                        route(3);
                        break;
                };
                avp_delete("i:13/g");

}; # End of "if(uri==myself)"


append_hf("P-hint: usrloc applied\r\n"); route(1);

        # if user is on-line and is in Voicemail group, enable redirection
        if (method == "INVITE" && isflagset(4)) {
                log(1, "invite for voicemail user->initiate failureroute[1]\n");
                t_on_failure("1");
        };
}

### ##### ####### ########## - ROUTES - ############### ################# 
##################

route[1] {

        # if client or server know to be behind a NAT, enable relay
        if (isflagset(6)) {
                log(1, "Route1: force rtp proxy!!!\n");
            force_rtp_proxy();
        };

        # NAT processing of replies; apply to all transactions (for example,
        # re-INVITEs from public to private UA are hard to identify as
        # NATed at the moment of request processing); look at replies
        t_on_reply("1");

        # send it out now; use stateful forwarding as it works reliably
        # even for UDP2TCP
        if (!t_relay()) {
                sl_reply_error();
        };
        log(1, "Route[1]: Send it out now!!!\n");
        break;
}

# !! Nathelper
onreply_route[1] {
        # NATed transaction ?
        # Not all 2xx messages have a content body so here we
        # make sure our Content-Length > 0 to avoid a parse error

    if (isflagset(6) && status =~ "(183)|2[0-9][0-9]") {
        fix_nated_contact();
        if (!search("^Content-Length:\ 0")) {
        force_rtp_proxy();
        };
    # otherwise, is it a transaction behind a NAT and we did not
    # know at time of request processing ? (RFC1918 contacts)
    } else if (nat_uac_test("1")) {
        fix_nated_contact();
    };
}

# -------------- SIP-to-PSTN call routed ---------------------

route[2]{ log(1,"route[2]:SIP-to-GW call routed \n");
        if(!t_relay()){
                sl_reply_error();
        };
        log(1, "Route[2]: Send it out now!!!\n");
}

# -------------- Same NAT Call Routing (no force rtpproxy) ----

route[3]{
        log(1," route[3]: UAs are in the same nat, NO force_rtp_proxy ");

        # What do I have to do here?

        if(!t_relay()){
                sl_reply_error();
        };
        log(1, "Route[3]: Send it out now!!!\n");
}

# --------------- Handling of Unavailable user ----------------
route[4] {
# non-Voip -- just send "off-line"
        if (!(method=="INVITE" || method=="ACK" || method=="CANCEL" || method=="BYE" || 
method=="OPTIONS")) {
                sl_send_reply("404", "Not Found");
                acc_db_request("404 Not Found", "missed_calls");
                log(1, "acc 404 Not Found 1 \n");
                break;
        };

if (!isflagset(4) && !method=="OPTIONS" && !method=="ACK" && !method=="BYE") { sl_send_reply("404", "Not Found and no voicemail turned on !! ");
                acc_db_request("404 Not Found", "missed_calls");
                log(1, " acc 404 Not Found and no voicemail \n");
                break;
        };

        # forward to voicemail adding prefix to simplify asterisk 
"extension.conf"
prefix("vm"); acc_db_request("404 Not Found -> Vm", "missed_calls");
        rewritehostport("192.168.2.131:5070");
        t_relay_to_udp("192.168.2.131", "5070");
}

# if forwarding downstream did not succeed, try voicemail running at Asterisk
failure_route[1]{
        if (t_check_status("408")){
                # revert_uri (); back to the original URI, makes me loose all 
lookup/rewrite stuff
                prefix("vm");
                rewritehostport ("192.168.2.131:5070");
                acc_db_request("408 Timeout   -> Vm", "missed_calls");
                append_branch();
                t_relay();
                break;
        } else if (t_check_status("486")){
                # revert_uri (); back to the original URI, makes me loose all 
lookup/rewrite stuff
                prefix("vm");
                rewritehostport ("192.168.2.131:5070");
                acc_db_request("486 Busy      -> Vm", "missed_calls");
                append_branch();
                t_relay();
                break;
        }
}

### The End ###


_______________________________________________
Users mailing list
Users@openser.org
http://openser.org/cgi-bin/mailman/listinfo/users

Reply via email to