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

From: Salvatore Loreto <[email-masked]>
Date: Thu, 1 Mar 2012 19:57:00 +0200

[as chair]

the draft-ietf-soc-overload-control-07 includes all the changes
that were agreed on the mailing list between Jan-04-2012 and Jan-16-2012

http://tools.ietf.org/html/draft-ietf-soc-overload-control-07

Volker and I, as chairs, believe the document has no remaining open issues,
and it is ready for WG last call evaluation.

Today we are starting a two-weeks working group last call.

This call end on  Thursday March 15th.

Comments and especially full and deep reviews of the draft are really 
appreciate. cheers Sal

Ciao
Salvatore Loreto

www.sloreto.com

---

From: Adam Roach <[email-masked]>
Date: Wed, 07 Mar 2012 13:13:06 -0600

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)
       }
     }
   }
}