[Devel] New module problem

Eliot Gable egable at broadvox.net
Thu Nov 16 15:20:25 CET 2006


We are investigating using OpenSER to offer a new feature to certain,
select customers. That feature is basically doing an ANI manipulation
and load balancing the manipulation across multiple ANI (for instance, a
call center who uses multiple ANIs as call back numbers and wants us to
load balance callbacks between them). As a proof of concept, I spent the
last two days writing a module for OpenSER to enable this functionality.
Essentially, this is what happens:

In the route[1] block, a function called kludge_ani() is called that
does the following:

Look up a list of possible ANIs to use, or an existing ANI if the call
is already setup.
Choose one at random.
Replace the ANI in the SIP message with the new one.
Store the original and new ANIs in a table that associates it with the
call, unless it is an existing call.
If it is an ACK to a previous BYE message, remove the entry in the
table.
If it is a BYE message or CANCEL, flag it as a BYE message or CANCEL.


In the onreply_route[1] block, a function called unkludge_ani() is
called that does the following:

Look up the saved, original ANI and restore it.
If it is a BYE message, flag that it is a BYE message.
If it is an ACK to a previous BYE message or an ACK to a CANCEL, remove
the entry in the table.

Everything works perfectly, except handling of the BYE messages. The
call sets up with the ANI manipulation taking place and both parties can
talk. A SIP trace shows that the messages still conform to the RFC.
However, when a BYE message is sent from one of the endpoints, they do
not seem to hit the route[1] or onreply_route[1] blocks, and thus do not
get handled by the kludge_ani() or unkludge_ani() functions. Seeing as
how a BYE message is not really a reply, but a request, I have tried
setting up a separate route block for handling the BYE messages. That
did not work either. It seems like the BYE messages are being handled
internally by either OpenSER or the transaction module (I am using
t_relay() and t_on_reply() to send and capture responses). If this is
being handled by the tm module or OpenSER directly, can someone point me
to where in the code this is happening so I can take a look at what it
does?

Any assistance in capturing and processing these BYE messages within the
scope of my module would be much appreciated.

As of right now, this is what the routing in my config looks like:

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");
                exit;
        };

        if (msg:len >=  2048 ) {
                sl_send_reply("513", "Message too big");
                exit;
        };

        # 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
        if (!method=="REGISTER")
                record_route();

        # subsequent messages withing a dialog should take the
        # path determined by record-routing
        if (loose_route()) {
                # mark routing logic in request
                append_hf("P-hint: rr-enforced\r\n");
        };

        if (!uri==myself) {
                # mark routing logic in request
                append_hf("P-hint: outbound\r\n");
                # if you have some interdomain connections via TLS
                #if(uri=~"@tls_domain1.net") {
                #       t_relay("tls:domain1.net");
                #       exit;
                #} else if(uri=~"@tls_domain2.net") {
                #       t_relay("tls:domain2.net");
                #       exit;
                #}
                route(1);
        };
        # Route lab responses back through reverse treatment route
        if(src_ip==192.168.1.2)
        {
                xlog("L_ERR", "Got message from 192.168.1.2.\n");
                t_on_reply("2");
                route(2);
        };
        if(src_ip==192.168.1.1)
        {
                xlog("L_ERR", "Got message from 192.168.1.1.\n");
                t_on_reply("1");
                xlog("L_ERR", "Sending to route block 1.\n");
                route(1);
        };

        route(3);
}

route[1] {
        rewritehostport("192.168.1.2:5060");
        kludge_ani();
        xlog("L_ERR", "Ani kludged. Relaying message.\n");
        if(!t_relay()) {
                xlog("L_ERR", "Could not relay message.\n");
                sl_reply_error();
        } else {
                xlog("L_ERR", "Relayed message correctly.\n");
        };
        exit;
}

route[2] {
        unkludge_ani();
        xlog("L_ERR", "Unkludged ani. Relaying message.\n");
        if(!t_relay()) {
                xlog("L_ERR", "Could not relay message from route block
2.\n");
                sl_reply_error();
        } else {
                xlog("L_ERR", "Relayed message from route block 2.\n");
        }
        exit;
}

onreply_route[1] {
        unkludge_ani();
        xlog("L_ERR", "Unkludged ani. Relaying message.\n");
        exit;
}

onreply_route[2] {
        kludge_ani();
        xlog("L_ERR", "Kludged ani. Relaying message.\n");
        exit;
}

route[3] {
        sl_reply_error();
}

Please keep in mind that as of Friday last week, I had never even heard
of OpenSER, so I am relatively new at this. If I have made some obvious
mistake, please let me know.

Eliot Gable
Operations Engineer
CCNA, CWNA, CWSP, Network+, Security+
Broadvox, LLC
1228 Euclid Avenue
Suite 390
Cleveland, OH 44115-1800
216-373-4808
 




More information about the Devel mailing list