Re: [sip-overload] WGLC: draft-ietf-soc-overload-control

Adam Roach <adam@nostrum.com> Wed, 07 March 2012 19:13 UTC

Return-Path: <adam@nostrum.com>
X-Original-To: sip-overload@ietfa.amsl.com
Delivered-To: sip-overload@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id EA7E611E8072 for <sip-overload@ietfa.amsl.com>; Wed, 7 Mar 2012 11:13:19 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -102.484
X-Spam-Level:
X-Spam-Status: No, score=-102.484 tagged_above=-999 required=5 tests=[AWL=0.116, BAYES_00=-2.599, SPF_PASS=-0.001, USER_IN_WHITELIST=-100]
Received: from mail.ietf.org ([12.22.58.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rQ3X0Bbwf94P for <sip-overload@ietfa.amsl.com>; Wed, 7 Mar 2012 11:13:19 -0800 (PST)
Received: from nostrum.com (nostrum-pt.tunnel.tserv2.fmt.ipv6.he.net [IPv6:2001:470:1f03:267::2]) by ietfa.amsl.com (Postfix) with ESMTP id 1FD9321F85AA for <sip-overload@ietf.org>; Wed, 7 Mar 2012 11:13:18 -0800 (PST)
Received: from dn3-228.estacado.net (vicuna-alt.estacado.net [75.53.54.121]) (authenticated bits=0) by nostrum.com (8.14.3/8.14.3) with ESMTP id q27JD6tk082593 (version=TLSv1/SSLv3 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO); Wed, 7 Mar 2012 13:13:08 -0600 (CST) (envelope-from adam@nostrum.com)
Message-ID: <4F57B342.2000209@nostrum.com>
Date: Wed, 07 Mar 2012 13:13:06 -0600
From: Adam Roach <adam@nostrum.com>
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0) Gecko/20120129 Thunderbird/10.0
MIME-Version: 1.0
To: Salvatore Loreto <salvatore.loreto@ericsson.com>
References: <4F4FB86C.2030908@ericsson.com>
In-Reply-To: <4F4FB86C.2030908@ericsson.com>
Content-Type: text/plain; charset="ISO-8859-1"; format="flowed"
Content-Transfer-Encoding: 7bit
Received-SPF: pass (nostrum.com: 75.53.54.121 is authenticated by a trusted mechanism)
Cc: Volker Hilt <volker.hilt@alcatel-lucent.com>, "sip-overload@ietf.org" <sip-overload@ietf.org>
Subject: Re: [sip-overload] WGLC: draft-ietf-soc-overload-control
X-BeenThere: sip-overload@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: SIP Overload <sip-overload.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/sip-overload>, <mailto:sip-overload-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/sip-overload>
List-Post: <mailto:sip-overload@ietf.org>
List-Help: <mailto:sip-overload-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/sip-overload>, <mailto:sip-overload-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 07 Mar 2012 19:13:20 -0000

I'm a bit confused by the algorithm described in section 6.3.

First, it's not clear whether this is intended to apply to outbound 
messages (i.e., "get_sip_msg" is getting a message from an internal 
queue of things to be sent on the network) or inbound messages (i.e., 
"get_sip_msg" is getting a message from the network for processing). The 
introduction to 6.3 obliquely hints that it might be for outbound 
messages, but it's not really all that clear.

In any case, the pseudocode starts:

> cat1 := 40.0          // Category 1 --- subject to reduction
> cat2 := 100.0 - cat1  // Category 2 --- Not subject to
>                       // reduction.  40/60 mix.
> in_oc := false        // Not operating under overload
>
> while (true)  {
>   sip_msg := get_sip_msg()
>   if (is_response(sip_msg))  {
>       process_msg(sip_msg)
>   }
>   else if (is_request(sip_msg))  {
>
>     // Determine if server wants to enter overload or is
>     // in overload
>     in_oc := extract_in_oc(sip_msg)
>
>     // Get validity value
>     oc_validity := extract_oc_validity(sip_msg)
>
>     // Get oc parameter value
>     oc_value := extract_oc_value(sip_msg)
>
>     pct_to_reduce := oc_value / cat1 * 100
>     // Example: if oc=10,
>     // server uses 10 / 40 * 100 = 25 or 25% of messages in
>     // Category 1 can be reduced.
> ...

If you make assumptions about functions based on their names, this 
attempts to extract oc value and oc validity information from the SIP 
*request* messages. My reading of the rest of this document is that 
*requests* will only have an empty, bare "oc" parameter in them. The 
actual overload control information appears in *responses*. Right?

On the other hand, if this is really for outbound messages, then what 
you need to do is store the OC data received from inbound responses 
(which would be in a processing loop not shown here), and the handling 
for outbound messages would really be computing the destination and then 
looking up any overload information that might have been stored for that 
destination. Right?

There's also the rather confusing bit here:

>
>       // Either Category 1 or Category 2
>       assign_msg_to_category(sip_msg)
>
>       if (oc_validity is in effect)  {
>         process_msg(get_msg_from_cat2())
>         sip_msg := get_msg_from_cat1()
>
>         // Draw a random number between 1 and 100
>         r := random()
>
>         if (r <= pct_to_reduce)  {
>             // Do not send to server, handle locally by
>             // generating a final response
>         }
>         else  {
>           process_msg(sip_msg)
>         }

Is the intention here that the message, if it is in category 2, is 
always sent, while the message, if it is in category 1, is subject to 
the shaping rules? If so, this seems a rather baroque way to effect 
that. Don't you mean something more like:


       // Either Category 1 or Category 2
       category := assign_msg_to_category(sip_msg)

       if (oc_validity is in effect)  {
         if (category == 2) {
           process_msg(sip_msg)
         }
         else
         {

           // Draw a random number between 1 and 100
           r := random()

           if (r <= pct_to_reduce)  {
               // Do not send to server, handle locally by
               // generating a final response
           }
           else  {
             process_msg(sip_msg)
         }

Except that's not quite right, since oc can be larger than cat 1. For 
example, if we use the 40/60 mix you have in the draft, your proposed 
amount to reduce looks like:

     pct_to_reduce := oc_value / cat1 * 100
     pct_to_reduce := 50 / 40 * 100
     pct_to_reduce := 125

Of course, a 125% reduction in category 1 messages isn't possible, so 
you're forced into reduction of category 2 messages. In other words, you 
need to calculate pct_to_reduce based on the message type, and take 
appropriate action when oc > cat1.

Finally, if you look at the codepath where "in_oc" is true but 
"oc_validity is in effect" is false, then the message is never 
processed. I think you really want to combine these into a single 
logical statement like:

     if (in_oc == false && oc_validity is in effect)  {
       send_message_to_network(sip_msg)
     }


So, taking the above assumptions into account, I think you really want 
something that looks more like:

cat1 := 40.0          // Category 1 --- subject to reduction
cat2 := 100.0 - cat1  // Category 2 --- Not subject to
                       // reduction.  40/60 mix.
in_oc := false        // Not operating under overload

while (true)  {
   sip_msg := get_outbound_sip_msg()
   if (is_response(sip_msg))  {

     if (sip_msg.via has oc parameter)) {
       add_overload_metrics(sip_msg)
     }

     send_message_to_network(sip_msg)
   }
   else if (is_request(sip_msg))  {

     destination := get_next_hop(sip_msg)

     // Determine if server wants to enter overload or is
     // in overload
     in_oc := lookup_in_oc(destination)

     // Get validity value
     oc_validity := lookup_oc_validity(destination)

     // Get oc parameter value
     oc_value := lookup_oc_value(destination)


     if (in_oc == false or oc_validity is not in effect)  {
       send_message_to_network(sip_msg)
     }
     else  {

       // Either Category 1 or Category 2
       category := assign_msg_to_category(sip_msg)

       if (category == 1) {
         pct_to_reduce := min (oc_value / cat1 * 100, 100)
         // Example: if oc=10,
         // server uses 10 / 40 * 100 = 25 or 25% of messages in
         // Category 1 can be reduced.
       }
       else {
         pct_to_reduce := max(0, oc_value / cat1 * 100 - 100)
         // Example: if oc=50,
         // server uses 50 / 40 * 100 - 100 = 25 or 25% of messages in
         // Category 2 can be reduced.
       }

       // Draw a random number between 1 and 100
       r := random()

       if (r <= pct_to_reduce)  {
           // Do not send to server, handle locally by
           // generating a final response
       }
       else  {
         send_message_to_network(sip_msg)
       }
     }
   }
}