Subject: [Sip] loop fix

From: Juha Heinanen <[email-masked]>
Date: Fri, 8 Sep 2006 17:17:01 +0300

why can't proxy check when it receives an initial request that it
doesn't already have a pending transaction with the same call id/request
uri/from tag?

-- juha

_______________________________________________
Sip mailing list  https://www1.ietf.org/mailman/listinfo/sip
This list is for NEW development of the core SIP Protocol
Use [email-masked] for questions on current sip
Use [email-masked] for new developments on the application of sip

---

From: Thomas Froment <[email-masked]>
Date: Fri, 08 Sep 2006 16:36:36 +0200

> doesn't already have a pending transaction with the same call id/request
Loop detection aims at distinguishing "normal" loops (called "Spirals") 
to unwanted ones (the "loops"), which may cause the request to loop 
forever if nothing else is done...

---

From: Juha Heinanen <[email-masked]>
Date: Fri, 8 Sep 2006 17:46:08 +0300

> forever if nothing else is done...

if request "spirals" normally back to the proxy, doesn't its request uri
change somehow?

-- juha

---

From: Thomas Leseney <[email-masked]>
Date: Fri, 08 Sep 2006 16:55:06 +0200

Not necessarily. An IMS S-CSCF may proxy a request to several AS.
Call id, from tag and RURI do not change. Internal state of the S-CSCF
ensures that the request spirals but does not loop.

Thomas

---

From: Juha Heinanen <[email-masked]>
Date: Fri, 8 Sep 2006 18:01:49 +0300

> ensures that the request spirals but does not loop.

IMS example doesn't count to me.  give me an example in regular rfc3261
environment.

-- juha

---

From: David Benoit <[email-masked]>
Date: Fri, 8 Sep 2006 14:34:48 -0300

This is exactly why you have to decrement the Max-Forwards header each
time a message is forwarded.  (RFC 3261 Section 8.1.1.6)

Even if a call comes into a proxy, goes out of the proxy, and comes back
in, that doesn't necessarily mean there is something wrong.  If it
continues to follow the same path, it is, but a loop within a call is
completely valid.  An infinite loop is undesirable.  Max-Forwards solves
this problem.

Detection of a loop and sending a 482 Loop Detected is a "MAY" suggestion,
not a "MUST" requirement.  It is optional.

David

-- 
[email-masked] | phone: 902-832-2649  fax: 902-832-1015
 "Complex problems have simple, neat and wrong solutions" - H. L. Menken

---

From: Juha Heinanen <[email-masked]>
Date: Fri, 8 Sep 2006 21:02:32 +0300

> time a message is forwarded.  (RFC 3261 Section 8.1.1.6)

sure, but i still haven't got an example where in rfc3261 sip
environment, an initial request would, without looping, come twice to
the proxy having the same request-uri, call id, and from tag.

-- juha

---

From: "Vijay K. Gurbani" <[email-masked]>
Date: Fri, 08 Sep 2006 13:57:16 -0500

> not a "MUST" requirement.  It is optional.

It was made optional in rfc3261, but that is changing.

The current wisdom is that loop detection is optional only if
the cardinality of the forked set is 1.  If you are forking to
multiple destinations (i.e., >= 2), it is a MUST.  See
http://www.ietf.org/internet-drafts/draft-ietf-sip-fork-loop-fix-03.txt

Thanks.

- vijay
-- 
Vijay K. Gurbani  vkg@{lucent.com,research.bell-labs.com,acm.org}
Bell Laboratories, Lucent Technologies, Inc.
2701 Lucent Lane, Rm. 9F-546, Lisle, Illinois 60532 (USA)

---

From: "kasturi Narayanan" <[email-masked]>
Date: Fri, 8 Sep 2006 14:29:47 -0500

Again not an example, which is used often
A Proxy Routes the call to a Redirect Server which adds a route header and
sends the call back to the proxy to route it based on the Route-header. U
may as well ask why the Redirect Server did not route it directly.
May be for some valid security/policy reasons. But since it is a possibility
it needs to be supported.

Kasturi

-----Original Message-----
From: Juha Heinanen [mailto:[email-masked]] 
Sent: Friday, September 08, 2006 1:03 PM
To: David Benoit
Cc: [email-masked]
Subject: Re: [Sip] loop fix

-- juha

---

From: "Pete Cordell" <[email-masked]>
Date: Fri, 8 Sep 2006 21:12:28 +0100

----- Original Message From: "Juha Heinanen" <jh@xxxxx>

> IMS example doesn't count to me.  give me an example in regular rfc3261

Maybe contrived but how about...

Our proxy gets a request for x@y and routes the request to B.  B turns out 
to be a proxy decides that x@y is not here at the moment and forwards the 
request elsewhere.  Loads of helpful proxies end up saying x@y is not here, 
but I know where they are rather than returning 404 or something. 
Eventually the request ends up back at our proxy.  Our proxy looks at all 
the Vias and sees an attempt has been made to contact x@y via B.  As an 
alternative, this time it decides to send the request out to C in the hope 
that that will find the real x@y.  The request could conceivably go through 
our proxy a number of times doing this.  I don't see that the URI has to 
change each time it does.

Pete.
--
=============================================
Pete Cordell
Tech-Know-Ware Ltd
                         for XML to C++ data binding visit
                         http://www.tech-know-ware.com/lmx
                         (or http://www.xml2cpp.com)
=============================================

---

From: "Pete Cordell" <[email-masked]>
Date: Fri, 8 Sep 2006 22:26:46 +0100

It's conceivable you could have an outer proxy that is hardened from a DoS 
or load balancing point of view, which always routes to a proxy behind a 
firewall that makes the actual routing decision.  The routing proxy would 
then sends the request back to the hardened proxy for onward routing using 
the Route header to convey its instructs as you suggest.

Pete.
----- Original Message ----- 
From: "kasturi Narayanan" <[email-masked]>
To: "'Juha Heinanen'" <[email-masked]>; "'David Benoit'" 
<[email-masked]>
Cc: <[email-masked]>
Sent: Friday, September 08, 2006 8:29 PM
Subject: RE: [Sip] loop fix

---

From: Juha Heinanen <[email-masked]>
Date: Sat, 9 Sep 2006 09:36:50 +0300

kasturi Narayanan writes:

 > sends the call back to the proxy to route it based on the
 > Route-header.

this example doesn't count to me either.  for security reasons, my proxy
only accepts an initial request containing pre-loaded route in case that
set contains only one element for the proxy itself.

-- juha

---

From: Juha Heinanen <[email-masked]>
Date: Sat, 9 Sep 2006 09:46:25 +0300

Pete Cordell writes:

 > that that will find the real x@y.  

sorry, i don't count this either.  my proxy doesn't do routing decisions
based on via headers (which would be very time consuming).

-- juha

---

From: Juha Heinanen <[email-masked]>
Date: Sat, 9 Sep 2006 10:05:13 +0300 (EEST)

Pete Cordell writes:

 > firewall that makes the actual routing decision.  

since the proxy behind makes the routing decisions, it could also take
care of loop detection.  if you want to do loop detection in the outer
proxy, you could configure it to do so only for requests from outside
and then again, it would suffice to do matching of r-uri, call-id, and
from tag.

all examples so far have dealt with some special circumstances that
either don't exist in my world or can be taken care by special
configuration.  i got an impression from the loop fix internet draft,
that this complicated extra via thing is needed for everyday operation
of regular proxies in order to prevent loops due to forking.  so far,
i'm not convinced.

in summary: no one has yet been able to justify that the via detection
mechanism is really needed in normal rfc3261 environment.

-- juha

---

From: "Pete Cordell" <[email-masked]>
Date: Sat, 9 Sep 2006 09:54:44 +0100

----- Original Message From: "Juha Heinanen" <jh@>

> configuration.

Although esoteric, my expectation is that as time goes on call routing etc. 
will become more complicated, and what seems off the wall today will become 
common place tomorrow.  SIP after all is supposed to allow us all to define 
our own wacky services, and doubtlessly a number of these will get chained 
together, possibly like a Unix command pipe.  Hence pushing the envelope 
here.

> i got an impression from the loop fix internet draft,

I think the main difference between what you are doing and the loop fix 
draft is about is that you have a stateful proxy and loop fix describes a 
way of doing it statelessly.  Perhaps the draft should say that if you have 
other means of accessing the state that the loop fix draft would otherwise 
put into the via headers, then you don't need to operate as the loop fix 
draft says.  It may say that already.

Pete.

---

From: Juha Heinanen <[email-masked]>
Date: Sat, 9 Sep 2006 12:28:09 +0300

> together, possibly like a Unix command pipe.  Hence pushing the envelope 

sure you need special means to cope with esoteric situations, but loop
fix draft doesn't state that it is needed for fixes esoteric corner
cases, but common forking cases like the example that it contains.  my
problem is that i don't understand why the via mechanism is needed to
solve the looping problem in its example.

 > draft says.  It may say that already.

forking statelessly is not a good idea for many reasons.  also, the
example in the loop fix draft deals with stateful proxies.

i must be missing something big here, since loop fix draft is authored
by well known sip people.  what is it?

-- juha

---

From: "Pete Cordell" <[email-masked]>
Date: Sat, 9 Sep 2006 17:05:33 +0100

----- Original Message From: "Juha Heinanen"

> by well known sip people.  what is it?

I might have been getting over complicated!

One thing you have to do is tell the difference between an INVITE 
re-transmission (which you would want to forward) and a loop (which you 
don't want to forward).

I think only the message itself can tell you this, as looking up local state 
based on uri, from tag and so on would not be sufficient to tell if the same 
message had already been processed.

As Via records the path of the message, this is the sensible place to look 
for the messages routing history, and work out whether it has passed through 
this proxy before.  The loop-fix draft is a recommendation of how to do 
this, but does allow for other schemes.

Pete.

---

From: Juha Heinanen <[email-masked]>
Date: Sat, 9 Sep 2006 19:46:54 +0300

> re-transmission (which you would want to forward) and a loop (which you 

statefull proxy takes of re-transmissions automatically.  there is no
need to study via records.

-- juha

---

From: "Vijay K. Gurbani" <[email-masked]>
Date: Sat, 09 Sep 2006 12:46:03 -0500

> by well known sip people.  what is it?

Juha: The basic problem was that people were eschewing loop
detection in favor of simply inserting a Max-Forwards.  In
rfc2543, loop detection for proxies was mandatory; this was
normatively relaxed in rfc3261.  As a result, newer
implementations were not doing loop detection at all (although
those implementors that were following SIP from pre-rfc2543
probably left the code in as they moved to rfc3261).

If the newer implementations depend on M-F to terminate loops,
they will have the amplification attack mentioned in the loop-fix
draft.  The loop-fix draft simply puts things back as they
were in rfc2543 wrt proxies and loop detection (i.e., mandating
it).  In addition, since our collective wisdom in SIP has increased
since rfc2543, there is additional text in loop-fix that
guides implementors when to do it (>=2 forked branches, which
headers to include) and when not (using outbound, for example).

Thanks.

- vijay

---

From: Juha Heinanen <[email-masked]>
Date: Sat, 9 Sep 2006 21:10:27 +0300

Vijay K. Gurbani writes:

 > The loop-fix draft simply puts things back as they

that is all fine, but i'm still waiting an rfc3261 based example where
simply comparing call-id/r-uri/from tag to pending initial request
transactions doesn't solve the problem.  loop-fix draft has Alternative
solutions section that doesn't even mention this simple solution even
when it fixes the loop in the example.  instead the draft proposes a
much heavier solution.

-- juha

---

From: "Pete Cordell" <[email-masked]>
Date: Sat, 9 Sep 2006 20:51:18 +0100

> need to study via records.

I have to admit I'm coming around to your way of thinking!

Thinking aloud, if the issue is mainly forking proxies (Max-Forwards taking 
care of looping for other proxies), then we are talking about stateful 
proxies.  For a stateful proxy to forward a request in response to an 
incoming request, it must decide that it is a new transaction.  This is 
because if it is deemed to be an existing transaction, then it will 
terminate the request in the existing Server Transaction handler for the 
transaction.  It does as if it is difficult to get a message explosion from 
those set of circumstances.

I wonder if loop-fix is a legacy from RFC 2543 days when forking proxies 
only SHOULD be stateful and Max-Forwards for optional.  RFC 2543 was also 
less prescriptive about what a stateful proxy did.  Perhaps loop-fix solves 
the the problem in 2543 space, but it is not actually needed when entities 
are 3261 compliant!

So I'll agree it's a question worth asking, but not sure I'm ready to chuck 
loop-fix out yet!

Pete.

---

From: "Vijay K. Gurbani" <[email-masked]>
Date: Sat, 09 Sep 2006 16:48:28 -0500

> when it fixes the loop in the example.  instead the draft proposes a

At least in my reading of loop-fix, I don't think it is precluding
you from hashing Call-ID/R-URI/From tag for the second part of the
branch parameter value.  All it is saying is that also include
the Route header field values, and any other values that are
used by the location service logic.

I re-read loop-fix again, and I think it will probably be much
clearer if included a bit more instructions on the headers
to include.  RFC3261 says:

       A common way to create this value is to compute a
       cryptographic hash of the To tag, From tag, Call-ID header
       field, the Request-URI of the request received (before
       translation), the topmost Via header, and the sequence number
       from the CSeq header field, in addition to any Proxy-Require
       and Proxy-Authorization header fields that may be present.

loop-fix could conceivably state that:

       A common way to create this value is to compute a
       cryptographic hash of the To tag (if present), From tag,
       Call-ID header field, the Request-URI of the request received
       (before translation), the sequence number from the CSeq
       header field, any Route header field values used during
       processing the request and any other values used by the
       location service logic while processing this request.

If because of simplicity your implementation disregards the last
two (Route headers and location service logic), chances are still
good that it will catch most of the loops.

Thanks.

- vijay

---

From: Juha Heinanen <[email-masked]>
Date: Sun, 10 Sep 2006 09:28:10 +0300

> used by the location service logic.

yes, but my point is why to calculate the hash at all and include it in
via header.  why not just compare those fields, say, one at a time
starting, for example, from call-id to currently pending initial
transactions?  if call-id is not found, there is no loop and nothing
else needs to be compared.

-- juha

---

From: Theo Zourzouvillys <[email-masked]>
Date: Sun, 10 Sep 2006 09:43:41 +0100

> else needs to be compared.

i can think of 3 common reasons you might want to place a hash in the Via as 
opposed to searching local transactions, which may or may not apply depending 
on the implementation:

(1) speed - if you have a large number of active transactions, then it's 
almost certainly a lot faster to construct and compare a hash in X number of 
via headers than search all the transactions received on that particular 
transport.  any multi threaded design would require at minimum a read lock on 
a list of transactions - doesn't sound to efficient to me!

(2) resilience - a crashed proxy would still be able to perform loop 
detection, even after loosing all of it's state - assuming it keeps 
transactions in memory and not committed elsewhere before forwarding; imagine 
some evil person managed to find some way to crash your proxy just after 
sending the requests out and it immediately restarted.  your loop detection 
would be pointless unless kept outside of the processes memory [1] if you 
didn't keep it in the Via header, although you obviously have other problems 
too :)

(3) scalability - loop may go through different proxies when load balancing.  
KEeping the hash in the via header allows peer proxies to detect and stop 
looped requests quicker than it would otherwise.

Kind Regards,

 ~ Theo

1 - assuming you're using a "normal" architecture :)

-- 
Theo P. Zourzouvillys
http://www.crazygreek.co.uk
[email-masked]

---

From: Juha Heinanen <[email-masked]>
Date: Sun, 10 Sep 2006 18:13:32 +0300

theo,

thanks for your reply.  it is the first that gives some real insight to
the issue.  these kind of comments should appear in the i-d, but they
don't.

 > almost certainly a lot faster to construct and compare a hash in X
 > number of via headers than search all the transactions received on
 > that particular transport.  

in some implementations this is true.  if it is not true in all
implementations, then the i-d should not give one SHOULD implementation
solution.

 > transactions in memory and not committed elsewhere before forwarding; 

this i don't quite understand.  even if proxy looses all state, doesn't
it rebuild that state next time it receives the looped request again and
will detect the loop during the following round?

 > (3) scalability - loop may go through different proxies when load
 > balancing. KEeping the hash in the via header allows peer proxies to
 > detect and stop looped requests quicker than it would otherwise.

this is not a valid reason, since if there are multiple proxies, they
may be from different vendors and since there is no standardized way to
calculate and add the hash into via header, one proxy cannot interpret
the via header added by another proxy.

-- juha

---

From: Juha Heinanen <[email-masked]>
Date: Sun, 10 Sep 2006 18:21:10 +0300

Theo Zourzouvillys writes:

 > (1) speed - if you have a large number of active transactions, then
 > it's almost certainly a lot faster to construct and compare a hash in
 > X number of via headers than search all the transactions received on

theo,

i'm coming back to this one.  in the proposed hash-to-via solution,
proxy has to calculate that hash for every initial request, which is not
free.  in the the call-id/r-uri comparison implementation nothing is
inserted into via header and thus nothing needs to be calculated.

what comes to call-id loookup speed, it depends how the proxy hashes its
transactions.

-- juha

---

From: [email-masked]
Date: Sun, 10 Sep 2006 23:51:26 -0400

From: Juha Heinanen <[email-masked]>

What you asked originally is:

The reason is that there's nothing preventing a proxy from using
various other headers for making routing decisions, and it's rather
easy to construct situations where the "obvious" solution to a routing
problem can lead to multiple transactions with the same
Call-ID/request-URI at one proxy.  Consider routing based on language
and media preferences.  Perhaps none of these are implemented right
now in situations you'd call "normal", but people are worried about
adopting a solution that would be a straitjacket.

In regard to the solution in the I-D, I did not participate in the
discussions that led up to it, but perhaps you could ask for a fuller
motivation in the I-D of the chosen solution.

But since this solution is a SHOULD, if you find it to be burdensome
to implement, you have the leeway to alter it.  But you should be
careful -- your proxy might be participating in a legitimate spiral
that is broken by some other proxy in the loop acting on some header
your proxy ignores.

Dale

---

From: Theo Zourzouvillys <[email-masked]>
Date: Mon, 11 Sep 2006 05:36:44 +0100

On Sunday 10 September 2006 16:13, Juha Heinanen <[email-masked]> wrote:

>  > (1) speed - if you have a large number of active transactions, then it's
>  > almost certainly a lot faster to construct and compare a hash in X
>  > number of via headers than search all the transactions received on
>  > that particular transport.  
>

As it is SHOULD (aka 'RECOMMENDED'), you have the flexibility of doing it in 
other ways if your particular situation requires it - but as most 'common' 
implementations will worry about the things listed here, then SHOULD is the 
right force for it in my opinion, as there are (as per rfc2119) "valid 
reasons in particular circumstances to ignore a particular item, but the full 
implications must be understood and carefully weighed before choosing a 
different course."

>  > (2) resilience - a crashed proxy would still be able to perform loop
>  > detection, even after loosing all of it's state - assuming it keeps
>  > transactions in memory and not committed elsewhere before forwarding;
>

Only after it looped again after crashing, and that assumes it's not already 
crashed again since.  Given that the attack vector that the I-D is trying to 
fix, i think it is sensible for it to catch a loop between crashes of an 
element, too.

fork-loop-fix-03, 3.  Vulnerability: Leveraging Forking to Flood a Network:

   [...]
   It is interesting to note that a few proxies rebooted during
   the scenario, and rejoined in the attack when they restarted (as long
   as they maintained registration state across reboots).  This points
   out that if this attack were launched on the Internet at large, it
   might require coordination among all the affected elements to stop
   it.

>  > (3) scalability - loop may go through different proxies when load
>  > balancing. KEeping the hash in the via header allows peer proxies to
>  > detect and stop looped requests quicker than it would otherwise.
>

indeed, with multiple vendors.  but none the less, it's a reason a proxy may 
want to use Via hashes rather than internally (which is what you asked).

 ~ Theo

---

From: "Jeroen van Bemmel" <[email-masked]>
Date: Mon, 11 Sep 2006 09:01:16 +0200

Juha,

Loop detection currently works the way it does to accomodate stateless 
proxies. It is the least common denominator; it will also work for stateful 
proxies, so there is no need to define separate mechanisms to achieve the 
same goal. That is a benefit

It is true that you can also detect loops by searching through existing 
state, with the aforementioned drawbacks that it won't work as well across 
reboots (I consider the performance of the lookup an implementation issue, 
it can be made efficient).

For the forking scenario, the proxy must by definition be stateful. So one 
could use a lookup through existing state as a way to do loop detection. 
There is nothing in the draft that prevents this - hashing is RECOMMENDED, 
but nothing says you can't do it your way. In fact, loop detection is a 
completely local feature - a proxy only has to recognise its own detection 
mechanism. So as long as it keeps to standard RFC3261 syntax, there is not 
actually a need to standardize any particular mechanism - just stating that 
it MUST do loop detection is sufficient.

What I personally don't like about the recommended mechanism, is the 
overloading of Via branches for both transaction id and loop detection. IMHO 
a much better solution is to separate the two; I personally use

Via: SIP/2.0/UDP host:port;branch=z9h....;ld={loop hash}

And it would be nice if there were some way to detect if some proxy is doing 
loop detection or not. A separate parameter achieves this

Regards,

Jeroen

----- Original Message ----- 
From: "Theo Zourzouvillys" <[email-masked]>
To: "Juha Heinanen" <[email-masked]>
Cc: <[email-masked]>
Sent: Monday, September 11, 2006 6:36 AM
Subject: Re: [Sip] loop fix

reasons in particular circumstances to ignore a particular item, but the 
full

   [...]

 ~ Theo

---

From: Thomas Froment <[email-masked]>
Date: Mon, 11 Sep 2006 09:18:48 +0200

Juha Heinanen wrote:
> IMS example doesn't count to me. 
lol
>  give me an example in regular rfc3261 environment.
>   
this is in RFC 3261:

Spiral: A spiral is a SIP request that is routed to a proxy,
         forwarded onwards, and arrives once again at that proxy, but
         this time differs in a way that will result in a different
         processing decision than the original request.  Typically, this
         means that the request's Request-URI differs from its previous
         arrival.  A spiral is not an error condition, unlike a loop.  A
         typical cause for this is call forwarding.  A user calls
         [email-masked].  The example.com proxy forwards it to Joe's
         PC, which in turn, forwards it to [email-masked].  This
         request is proxied back to the example.com proxy.  However,
         this is not a loop.  Since the request is targeted at a
         different user, it is considered a spiral, and is a valid
         condition.

somebody already mentionned  this loop detection is optional in RFC 3261 but is going to become mandatory with  
http://www.ietf.org/internet-drafts/draft-ietf-sip-fork-loop-fix-03.txt, look at this, you have some examples...

---

From: "Pete Cordell" <[email-masked]>
Date: Mon, 11 Sep 2006 18:10:39 +0100

I've reflected a bit more on this...

A question... is it possible to arrange that two (non-forking) proxies end 
up bouncing a single request between them?  I would think it is.  In this 
case, even though you don't get the combinatorial explosion that you do for 
the forking case, I think a 1 to 70 amplification of messages is still quite 
significant and worth protecting against.

So I think the various weighting should be, forking proxies MUST do loop 
detection.  Other proxies SHOULD do loop detection (as opposed to MAY). 
It's important that the draft explains a method to do loop detection in the 
most general case (i.e. allowing for stateless proxies etc.), but 
technically I don't think it even has to be RECOMMENDED strength.

It would be good if in some way the loop detection algorithm could be 
normatively referenced so that it would be possible to say that such and 
such an implementation fully implements and conforms to the loop detection 
algorithm described in RFC XXXX, by just saying "implements RFC XXXX".  That 
might require two RFCs though; one to mandate/recommend loop detection, and 
another to described the suggested loop detection algorithm.  That may be 
too much work for the small gain though!

Pete.

----- Original Message ----- 
From: "Jeroen van Bemmel" <[email-masked]>
To: "Theo Zourzouvillys" <[email-masked]>; "Juha Heinanen" 
<[email-masked]>
Cc: <[email-masked]>
Sent: Monday, September 11, 20From [email-masked] Mon Sep 11 13:15:10 2006
From: "Pete Cordell" <[email-masked]>
To: "Jeroen van Bemmel" <[email-masked]>,
	"Theo Zourzouvillys" <[email-masked]>,
	"Juha Heinanen" <[email-masked]>
Subject: Re: [Sip] loop fix
Date: Mon, 11 Sep 2006 18:10:39 +0100
Cc: [email-masked]

I've reflected a bit more on this...

A question... is it possible to arrange that two (non-forking) proxies end 
up bouncing a single request between them?  I would think it is.  In this 
case, even though you don't get the combinatorial explosion that you do for 
the forking case, I think a 1 to 70 amplification of messages is still quite 
significant and worth protecting against.

So I think the various weighting should be, forking proxies MUST do loop 
detection.  Other proxies SHOULD do loop detection (as opposed to MAY). 
It's important that the draft explains a method to do loop detection in the 
most general case (i.e. allowing for stateless proxies etc.), but 
technically I don't think it even has to be RECOMMENDED strength.

It would be good if in some way the loop detection algorithm could be 
normatively referenced so that it would be possible to say that such and 
such an implementation fully implements and conforms to the loop detection 
algorithm described in RFC XXXX, by just saying "implements RFC XXXX".  That 
might require two RFCs though; one to mandate/recommend loop detection, and 
another to described the suggested loop detection algorithm.  That may be 
too much work for the small gain though!

Pete.

----- Original Message ----- 
From: "Jeroen van Bemmel" <[email-masked]>
To: "Theo Zourzouvillys" <[email-masked]>; "Juha Heinanen" 
<[email-masked]>
Cc: <[email-masked]>
Sent: Monday, September 11, 2006 8:01 AM
Subject: Re: [Sip] loop fix

> proxies. It is the least common denominator; it will also work for 
> stateful proxies, so there is no need to define separate mechanisms to 
> achieve the same goal. That is a benefit
>
> actually a need to standardize any particular mechanism - just stating 
> that it MUST do loop detection is sufficient.
>
> overloading of Via branches for both transaction id and loop detection. 
> IMHO a much better solution is to separate the two; I personally use
>
> And it would be nice if there were some way to detect if some proxy is 
> doing loop detection or not. A separate parameter achieves this
>
> Regards,
>
> Jeroen
>
>> > it's

---

From: Juha Heinanen <[email-masked]>
Date: Mon, 11 Sep 2006 20:31:09 +0300

Pete Cordell writes:

 > I think a 1 to 70 amplification of messages is
 > still quite significant and worth protecting against.

i agree.  where does 70 come from?  smells like yet another IMS
requirement :-) i have never seen even 20 "Received from" headers in
email messages and ip ttl is 32.

-- juha

---

From: David Benoit <[email-masked]>
Date: Mon, 11 Sep 2006 14:52:01 -0300

I'm sorry, but I'm still not convinced that any of this is going to help.
What, in any of this, prevents the following:

              A
              |
              P
             / \
            BB BB
            |   |
            P   P

Where A is a UA, P is a stateless proxy, and BB is a B2BUA.  The request
is going to fork from the proxy, arrive at the B2BUA, a _new_ (related
only internally to the B2BUA) call is then made to P and the tree grows
just as before.  It is not possible to detect the loop because the message
is not the same; it is a new transaction.  This new draft mentions nothing
about this, yet it is exactly the same problem.

Also, schemes such as these will only really protect against "friendly
fire" ... meaning it only really protects you against mis-configuration.
Anyone seriously out to destroy your proxy is going to at least not
forward on the headers such that they are detected as a loop.  You can't
assume that the malicious are ignorant.

The amplification problem can NOT be removed unless "you" are sending the
transaction to yourself.  That is the only way you can know that the
headers haven't been modified.

David

On Mon, Sep 11, 2006 at 06:10:39PM +0100, Pete Cordell wrote:
> the forking case, I think a 1 to 70 amplification of messages is still 
> quite significant and worth protecting against.
> 
> algorithm described in RFC XXXX, by just saying "implements RFC XXXX".  
> That might require two RFCs though; one to mandate/recommend loop 
> detection, and another to described the suggested loop detection algorithm. 
> That may be too much work for the small gain though!
> 
> Pete.
> --

---

From: Paul Kyzivat <[email-masked]>
Date: Mon, 11 Sep 2006 14:35:50 -0400

David,

Certainly it is possilbe to implement a scenario such as you show below.

Without loop detection and with Max-forwards of 70, such a thing will 
generate about 2^70 messages before max-forwards stops it. The 
difference compared to a non-b2bua case it that you will need 2^70-1 
b2bua call states to achieve this. It will presumably run out of 
capacity long before then.

This is of course a problem for B2BUAs. If we had any rules for them 
than we should probably require that they also implement loop detection.

	Paul

---

From: "Pete Cordell" <[email-masked]>
Date: Mon, 11 Sep 2006 19:56:06 +0100

----- Message From: "Juha Heinanen"

> email messages and ip ttl is 32.

The 70 I'm referring to is the default initial value of Max-Forwards (which 
leads to the 2^70 number being mentioned in the loop-fix draft).

As to why it is 70 and not some smaller value, I'm not sure.  The earliest 
reference I've found is comments about 2543-bis-06 where Jo Hornsby 
describes it as a "magically random figure"! 
(http://www1.ietf.org/mail-archive/web/sip/current/msg03463.html)  Had the 
IMS crowd infiltrated the ranks then? :-)

Pete.

---

From: Paul Kyzivat <[email-masked]>
Date: Mon, 11 Sep 2006 15:11:36 -0400

> email messages and ip ttl is 32.

I'm pretty sure the primary authors of 3261 would not have chosen this 
value based on IMS, even if IMS had been making requests back then.

As I recall, when this first came up at SipIt, it turned out that 
*every* implementation present used Max-Forwards:20 as the initial 
value. Nobody knew how that happened, since there has been nothing 
written that suggested that value. But even the "small" value of 2^20 
was plenty to swamp the network.

	Paul

---

From: David Benoit <[email-masked]>
Date: Mon, 11 Sep 2006 17:45:05 -0300

I think you may have missed my point.  The B2BUA would be in every segment
of the loop, inserted.  The tree would still grow to n^Max_Forwards (where
n is the number of forks... which I have had cause to have as many as 8).
My point is that loop detection doesn't work here.  At no stage of the
"looping" (which, would be better called an infinite "spiral") can you
detect that it is the same message.

As I said earlier, it can _only_ _always_ work if you end up sending it to
yourself, which you should be able to detect _before_ you send it.

There has to be better protection against such escalation.  But what?

David

On Mon, Sep 11, 2006 at 02:35:50PM -0400, Paul Kyzivat wrote:
> >>A question... is it possible to arrange that two (non-forking) proxies 
> >>end up bouncing a single request between them?  I would think it is.  In 
> >>this case, even though you don't get the combinatorial explosion that you 
> >>do for the forking case, I think a 1 to 70 amplification of messages is 
> >>It's important that the draft explains a method to do loop detection in 
> >>the most general case (i.e. allowing for stateless proxies etc.), but 
> >>such an implementation fully implements and conforms to the loop 
> >>detection algorithm described in RFC XXXX, by just saying "implements RFC 
> >>XXXX".  That might require two RFCs though; one to mandate/recommend loop 
> >>detection, and another to described the suggested loop detection 
> >>algorithm. That may be too much work for the small gain though!
> >>
> >>Pete.
> >>--
> >>>state, with the aforementioned drawbacks that it won't work as well 
> >>>across reboots (I consider the performance of the lookup an 
> >>>implementation issue, it can be made efficient).
> >>>
> >>>For the forking scenario, the proxy must by definition be stateful. So 
> >>>one could use a lookup through existing state as a way to do loop 
> >>>detection. There is nothing in the draft that prevents this - hashing is 
> >>>RECOMMENDED, but nothing says you can't do it your way. In fact, loop 
> >>>detection is a completely local feature - a proxy only has to recognise 
> >>>its own detection mechanism. So as long as it keeps to standard RFC3261 
> >>>syntax, there is not actually a need to standardize any particular 
> >>>mechanism - just stating that it MUST do loop detection is sufficient.
> >>>

---

From: "Samir Srivastava" <[email-masked]>
Date: Mon, 11 Sep 2006 16:44:24 -0500

Hi,

> There has to be better protection against such escalation.  But what?

  With so much interest on the loop fix, I thought it is good to bring
the other solutions to group's attention.

  Loop Avoidance is better than the Loop Detection. Loops are caused by
the installation of "bad bindings". The proposed solution checks the
validity of bindings before they are committed for the further request
routing.

The solution checks the SIP reachability of the contacts too before they
are committed. This is more useful when forwarding is installed on
multiple proxies. 

Proposed solution doesn't require checking for every transaction at
every proxy.

Draft is available at

<t>
http://www.ietf.org/internet-drafts/draft-srivastava-sipping-loop-avoida
nce-00.txt
</t>

It got comments from the group. Refer following threads for the solution
to them

http://www1.ietf.org/mail-archive/web/sipping/current/msg11084.html

http://www1.ietf.org/mail-archive/web/sipping/current/msg11085.html

http://www1.ietf.org/mail-archive/web/sipping/current/msg11097.html

Sorry it is taking long for the next version of the ID. Comments are
welcome. 

Thx
Samir

---

From: Paul Kyzivat <[email-masked]>
Date: Tue, 12 Sep 2006 18:14:51 -0400

David,

There are two cases here:
- the B2BUA is a complicit evil doer
- the B2BUA is a bystander

If the B2BUA is an evil doer, then there is no amplification. If the 
evil doer is willing to devote this much resource to the attack then we 
are perhaps helpless to solve it by these kinds of means.

If the B2BUA is a bystander, then IMO it has an obligation to do loop 
detection. How it would do that is a question. But because we don't 
currently do specs for B2BUAs we aren't likely to specify how.

	Paul

---

From: Paul Kyzivat <[email-masked]>
Date: Tue, 12 Sep 2006 18:14:51 -0400

David,

	Paul

---

From: David Benoit <[email-masked]>
Date: Wed, 13 Sep 2006 13:38:42 -0300

> are perhaps helpless to solve it by these kinds of means.

How is there no amplification?  My point is that all the B2BUA would have
to do is just that, back-to-back the call and the proxy that the loop is
made through can never detect it.  Does that make the loop detection
pointless?  No, but it does mean that it obviously does not solve the
whole problem.

> currently do specs for B2BUAs we aren't likely to specify how.

That's unfortunate as I don't use "proxies" that aren't B2BUAs.  I find it
much easier to write a B2BUA than a "proxy" since I have to know about all
the state of the transactions anyway.  I see no benefit to a proxy over a
B2BUA.

Here's the problem.  You want to protect against amplification.  Spiraling
calls are okay (presumably because they are taking a different "route" on
each loop.  We can't remove forking because that is too useful.

I really think the only reasonable protection the proxy can do is make
sure that the proxy is not sending a transaction to itself.  You should
never have a spiral that has a message going from A to A without going
through B.  A should know that it _is_ A and that sending to A is
pointless as it could otherwise determine what to do with the message
(either detect it as a loop, or apply different processing rules).

On the binding side of things, you have to protect against malicious
bindings.  There has to be some qualification that a binding is against an
endpoint that _can_not_ produce a loop.  For example, if you only allowed
bindings to be registered against a network element that was not allowed
to send messages back "in" but only "out".  In other words, make it
impossible on the layer 3 side of things for the messages to loop.  If you
want to protect your network, you have to control your network.  You can't
trust that the messages will be well formed, and you can't trust that a
binding won't try to create a loop.

David

> >>>>end up bouncing a single request between them?  I would think it is.  
> >>>>In this case, even though you don't get the combinatorial explosion 
> >>>>that you do for the forking case, I think a 1 to 70 amplification of 
> >>>>messages is still quite significant and worth protecting against.
> >>>>
> >>>>So I think the various weighting should be, forking proxies MUST do 
> >>>>loop detection.  Other proxies SHOULD do loop detection (as opposed to 
> >>>>MAY). It's important that the draft explains a method to do loop 
> >>>>detection in the most general case (i.e. allowing for stateless proxies 
> >>>>etc.), but technically I don't think it even has to be RECOMMENDED 
> >>>>strength.
> >>>>
> >>>>normatively referenced so that it would be possible to say that such 
> >>>>and such an implementation fully implements and conforms to the loop 
> >>>>detection algorithm described in RFC XXXX, by just saying "implements 
> >>>>RFC XXXX".  That might require two RFCs though; one to 
> >>>>mandate/recommend loop detection, and another to described the 
> >>>>suggested loop detection algorithm. That may be too much work for the 
> >>>>small gain though!
> >>>>
> >>>>Pete.
> >>>>--
> >>>>>It is true that you can also detect loops by searching through 
> >>>>>existing state, with the aforementioned drawbacks that it won't work 
> >>>>>as well across reboots (I consider the performance of the lookup an 
> >>>>>detection. There is nothing in the draft that prevents this - hashing 
> >>>>>is RECOMMENDED, but nothing says you can't do it your way. In fact, 
> >>>>>loop detection is a completely local feature - a proxy only has to 
> >>>>>recognise its own detection mechanism. So as long as it keeps to 
> >>>>>standard RFC3261 syntax, there is not actually a need to standardize 
> >>>>>any particular mechanism - just stating that it MUST do loop detection 
> >>>>>is sufficient.
> >>>>>
> >>>>>overloading of Via branches for both transaction id and loop 
> >>>>>detection. IMHO a much better solution is to separate the two; I 
> >>>>>personally use
> >>>>>

---

From: Paul Kyzivat <[email-masked]>
Date: Wed, 13 Sep 2006 14:06:50 -0400

> pointless?  No, but it does mean that it obviously does not solve the

My point is that to prevent the loop detection from working, even if the 
forking is done elsewhere, the B2BUA must be present in *every* 
iteration of the loop. Thus the resources required by the B2BUA scale 
linearly with the size of the problem it is attempting to create.

> the state of the transactions anyway.  I see no benefit to a proxy over a

It would be interesting to understand why you find yourself in this 
position. I think people here would like to arrange things so that kind 
of tactic isn't necessary.

> (either detect it as a loop, or apply different processing rules).

Its trivial to recognize sending to yourself. But it also isn't always 
wrong. Nor is it sufficient to prevent loops. The loop that goes from A 
to B to A ... is just a bad as the one that goes from A to A.

So I don't see why what you suggest is either necessary or sufficient.

> binding won't try to create a loop.

Except in very tightly controlled closed networks you will never be able 
to achieve this. And, I can never know that I am not routing to somebody 
that fails to do this.

	Paul