Hi,
 
Can anybody help me with these duplicate messages?
I guess the first message should be removed from the db, since it got a reply 
202.
Despite that, it end up again in the db.
Can you help me what I am doing wrong?
 
Many thanks
Marc
 
From: proy...@hotmail.com
To: sr-users@lists.sip-router.org
Date: Tue, 3 Jun 2014 21:38:32 +0000
Subject: [SR-Users] MSILO - dumped messages get duplicated




Hi,

I have a Kamailio 3.2 setup up and running. 
Recently I configured msilo for offline message store. Essentialy the setup 
runs fine. 

Messages to users without location info getting stored.
In case the user has location info, but cannot be reached, I made 
failover_route, so the messages getting stored in this case too.
Messages getting dumped at the next REGISTER.

However, I have a group of new mobile clients, with unstable connection.
It happens many times that they send a REGISTER, but the connection brakes 
afterwards.

It this case the message is getting dumped, but since it cannot be delivered, 
it runs on the failover_route which stores the message again.
However, the previous message is not removed from the db, so the same message 
is now twice in the db.
Next time the message either gets delivered in double, or in case of a new 
failure, it gets stored 2x2= four times.

I need to avoid this duplicates but still make sure the message get delivered 
sooner or later.
Any help is highly appreciated.

Here is my routing table:

thanks
Marc

####### Routing Logic ########


# Main SIP request routing logic
# - processing of any incoming SIP request starts with this route
route {

        # per request initial checks
        route(REQINIT);

        # NAT detection
        route(NAT);

        # handle requests within SIP dialogs
        route(WITHINDLG);

        ### only initial requests (no To tag)

        # CANCEL processing
        if (is_method("CANCEL"))
        {
                if (t_check_trans())
                        t_relay();
                exit;
        }

        if (is_method("MESSAGE"))
        {
         log(1,"-------------------------------------------------------->WE 
HAVE A NEW MESSAGE\n");
         route(MSILO_MESSAGE);
        }
        
        t_check_trans();

        # authentication
        route(AUTH);

        # record routing for dialog forming requests (in case they are routed)
        # - remove preloaded route headers
        remove_hf("Route");
        if (is_method("INVITE|SUBSCRIBE"))
                record_route();

        # account only INVITEs
        if (is_method("INVITE"))
        {
                setflag(FLT_ACC); # do accounting
        }

        # dispatch requests to foreign domains
        route(SIPOUT);

        ### requests for my local domains

        # handle presence related requests
        route(PRESENCE);

        # handle registrations
        route(REGISTRAR);

        if ($rU==$null)
        {
                # request with no Username in RURI
                sl_send_reply("484","Address Incomplete");
                exit;
        }

        # dispatch destinations to PSTN
        route(PSTN);

        # user location service
        route(LOCATION);

        route(RELAY);
}


route[RELAY] {
#!ifdef WITH_NAT
        if (check_route_param("nat=yes")) {
                setbflag(FLB_NATB);
        }
        if (isflagset(FLT_NATS) || isbflagset(FLB_NATB)) {
                route(RTPPROXY);
        }
#!endif


        /* example how to enable some additional event routes */
        if (is_method("INVITE")) {
                #t_on_branch("BRANCH_ONE");
                t_on_reply("REPLY_ONE");
                t_on_failure("FAIL_ONE");
        }

        if (!t_relay()) {
                sl_reply_error();
        }
        exit;
}

##storing offline messages
route[MSILO_MESSAGE]{
        if (lookup("location")){
        t_on_failure("FAIL_MESSAGE");
        t_relay();
        xlog("L_NOTICE","---------------------------------MI: ($mi), MB: 
($mb)\n");
        }else{
                xlog("L_NOTICE","------------------MESSAGE PROCESSING: location 
not found, storing offline message ID: ($ru)\n");
                m_store("$ru");
                sl_send_reply("202", "ACCEPTED");
                
                xlog("L_NOTICE","------------------MESSAGE PROCESSING: location 
not found, stored offline message ID: ($ru)\n");
};
        exit;
};

failure_route[FAIL_MESSAGE]{

    xlog("L_NOTICE","------------------MESSAGE PROCESSING: user cannot be 
reached, storing offline message ID: ($ou)\n");
    m_store("$ou");
    t_reply("202", "ACCEPTED");
    xlog("L_NOTICE","------------------MESSAGE PROCESSING: user cannot be 
reached, stored offline message ID: ($ou)\n");
    exit;
    }




# Per SIP request initial checks
route[REQINIT] {
#!ifdef WITH_ANTIFLOOD
        # flood dection from same IP and traffic ban for a while
        # be sure you exclude checking trusted peers, such as pstn gateways
        # - local host excluded (e.g., loop to self)
        if(src_ip!=myself)
        {
                if($sht(ipban=>$si)!=$null)
                {
                        # ip is already blocked
                        xdbg("request from blocked IP - $rm from $fu 
(IP:$si:$sp)\n");
                        exit;
                }
                if (!pike_check_req())
                {
                        xlog("L_ALERT","ALERT: pike blocking $rm from $fu 
(IP:$si:$sp)\n");
                        $sht(ipban=>$si) = 1;
                        exit;
                }
        }
#!endif

        if (!mf_process_maxfwd_header("10")) {
                sl_send_reply("483","Too Many Hops");
                exit;
        }

        if(!sanity_check("1511", "7"))
        {
                xlog("Malformed SIP message from $si:$sp\n");
                exit;
        }
}

# Handle requests within SIP dialogs
route[WITHINDLG] {
        if (has_totag()) {
                # sequential request withing a dialog should
                # take the path determined by record-routing
                if (loose_route()) {
                        if (is_method("BYE")) {
                                setflag(FLT_ACC); # do accounting ...
                                setflag(FLT_ACCFAILED); # ... even if the 
transaction fails
                        }
                        route(RELAY);
                } else {
                        if (is_method("SUBSCRIBE") && uri == myself) {
                                # in-dialog subscribe requests
                                route(PRESENCE);
                                exit;
                        }
                        if ( is_method("ACK") ) {
                                if ( t_check_trans() ) {
                                        # no loose-route, but stateful ACK;
                                        # must be an ACK after a 487
                                        # or e.g. 404 from upstream server
                                        t_relay();
                                        exit;
                                } else {
                                        # ACK without matching transaction ... 
ignore and discard
                                        exit;
                                }
                        }
                        sl_send_reply("404","Not here");
                }
                exit;
        }
}

# Handle SIP registrations
route[REGISTRAR] {
        if (is_method("REGISTER"))
        {
        
                
                if(isflagset(FLT_NATS))
                {
                        setbflag(FLB_NATB);
                        # uncomment next line to do SIP NAT pinging 
                        setbflag(FLB_NATSIPPING);
                }
                if (!save("location"))
                        sl_reply_error();
                        # MSILO - dumping user's offline messages
                        m_dump();
                        log(1,"-------------------------MESSAGE PROCESSING: 
dumping offline messages\n");
                        
                        exit;
        }
}

# USER location service
route[LOCATION] {

#!ifdef WITH_ALIASDB
        # search in DB-based aliases
        alias_db_lookup("dbaliases");
#!endif

        if (!lookup("location")) {
                switch ($rc) {
                        case -1:
                        case -3:
                                t_newtran();
                                t_reply("404", "Not Found");
                                exit;
                        case -2:
                                sl_send_reply("405", "Method Not Allowed");
                                exit;
                }
        }

        # when routing via usrloc, log the missed calls also
        if (is_method("INVITE"))
        {
                setflag(FLT_ACCMISSED);
        }
}

# Presence server route
route[PRESENCE] {
        if(!is_method("PUBLISH|SUBSCRIBE"))
                return;

#!ifdef WITH_PRESENCE
        if (!t_newtran())
        {
                sl_reply_error();
                exit;
        };

        if(is_method("PUBLISH"))
        {
                handle_publish();
                t_release();
        }
        else
        if( is_method("SUBSCRIBE"))
        {
                handle_subscribe();
                t_release();
        }
        exit;
#!endif
        
        # if presence enabled, this part will not be executed
        if (is_method("PUBLISH") || $rU==$null)
        {
                sl_send_reply("404", "Not here");
                exit;
        }
        return;
}

# Authentication route
route[AUTH] {
#!ifdef WITH_AUTH
        if (is_method("REGISTER"))
        {
                # authenticate the REGISTER requests (uncomment to enable auth)
                if (!www_authorize("$td", "subscriber"))
                {
                        www_challenge("$td", "0");
                        exit;
                }

                if ($au!=$tU)
                {
                        sl_send_reply("403","Forbidden auth ID");
                        exit;
                }
        } else {

#!ifdef WITH_IPAUTH
                if(allow_source_address())
                {
                        # source IP allowed
                        return;
                }
#!endif

                # authenticate if from local subscriber
                if (from_uri==myself)
                {
                        if (!proxy_authorize("$fd", "subscriber")) {
                                proxy_challenge("$fd", "0");
                                exit;
                        }
                        if (is_method("PUBLISH"))
                        {
                                if ($au!=$tU) {
                                        sl_send_reply("403","Forbidden auth 
ID");
                                        exit;
                                }
                        } else {
                                if ($au!=$fU) {
                                        sl_send_reply("403","Forbidden auth 
ID");
                                        exit;
                                }
                        }

                        consume_credentials();
                        # caller authenticated
                } else {
                        # caller is not local subscriber, then check if it calls
                        # a local destination, otherwise deny, not an open 
relay here
                        if (!uri==myself)
                        {
                                sl_send_reply("403","Not relaying");
                                exit;
                        }
                }
        }
#!endif
        return;
}

# Caller NAT detection route
route[NAT] {
#!ifdef WITH_NAT
        force_rport();
        if (nat_uac_test("19")) {
                if (method=="REGISTER") {
                        fix_nated_register();
                } else {
                        fix_nated_contact();
                }
                setflag(FLT_NATS);
        }
#!endif
        return;
}

# RTPProxy control
route[RTPPROXY] {
#!ifdef WITH_NAT
        if (is_method("BYE")) {
                unforce_rtp_proxy();
        } else if (is_method("INVITE")){
        
                rtpproxy_offer();
        }
        if (!has_totag()) add_rr_param(";nat=yes");
#!endif
        return;
}

# Routing to foreign domains
route[SIPOUT] {
        if (!uri==myself)
        {
                append_hf("P-hint: outbound\r\n");
                route(RELAY);
        }
}

# PSTN GW routing
route[PSTN] {
#!ifdef WITH_PSTN
        # check if PSTN GW IP is defined
        if (strempty($sel(cfg_get.pstn.gw_ip))) {
                xlog("SCRIPT: PSTN rotuing enabled but pstn.gw_ip not 
defined\n");
                return;
        }

        # route to PSTN dialed numbers starting with '+' or '00'
        #     (international format)
        # - update the condition to match your dialing rules for PSTN routing
        if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$"))
                return;

        # only local users allowed to call
        if(from_uri!=myself) {
                sl_send_reply("403", "Not Allowed");
                exit;
        }

        $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);

        route(RELAY);
        exit;
#!endif

        return;
}

# XMLRPC routing
#!ifdef WITH_XMLRPC
route[XMLRPC]
{
        # allow XMLRPC from localhost
        if ((method=="POST" || method=="GET")
                        && (src_ip==127.0.0.1)) {
                # close connection only for xmlrpclib user agents (there is a 
bug in
                # xmlrpclib: it waits for EOF before interpreting the response).
                if ($hdr(User-Agent) =~ "xmlrpclib")
                        set_reply_close();
                set_reply_no_connect();
                dispatch_rpc();
                exit;
        }
        send_reply("403", "Forbidden");
        exit;
}
#!endif

# Sample branch router
branch_route[BRANCH_ONE] {
        xdbg("new branch at $ru\n");
}

# Sample onreply route
onreply_route[REPLY_ONE] {
        xdbg("incoming reply\n");
#!ifdef WITH_NAT
        if ((isflagset(FLT_NATS) || isbflagset(FLB_NATB))
                        && status=~"(183)|(2[0-9][0-9])") {

                rtpproxy_answer();
        }
        if (isbflagset("6")) {
                fix_nated_contact();
        }
#!endif
}

# Sample failure route
failure_route[FAIL_ONE] {
#!ifdef WITH_NAT
        if (is_method("INVITE")
                        && (isbflagset(FLB_NATB) || isflagset(FLT_NATS))) {
                unforce_rtp_proxy();
        }
#!endif

        if (t_is_canceled()) {
                exit;
        }

        # uncomment the following lines if you want to block client 
        # redirect based on 3xx replies.
        ##if (t_check_status("3[0-9][0-9]")) {
        ##t_reply("404","Not found");
        ##      exit;
        ##}

        # uncomment the following lines if you want to redirect the failed 
        # calls to a different new destination
        ##if (t_check_status("486|408")) {
        ##      sethostport("192.168.2.100:5060");
        ##      append_branch();
        ##      # do not set the missed call flag again
        ##      t_relay();
        ##}
}



                                          

_______________________________________________
SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list
sr-users@lists.sip-router.org
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users                   
                  
_______________________________________________
SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list
sr-users@lists.sip-router.org
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users

Reply via email to