Subject: [Anima-signaling] GRASP relaying

From: Brian E Carpenter <[email-masked]>
Date: Sun, 3 Jan 2016 15:05:43 +1300

Happy New Year to the signaling design team. It's time to get
started again!

I wanted to update you on the question of how a GRASP node handles relaying.
You will remember that a node with more than one interface must relay
Discovery messages and Flood messages (which are link-local multicasts)
between interfaces. Obviously, prevention of multicast loops and storms
is important. Thus the GRASP spec has rules for this:

A. decrement the loop count in the objective being discovered/flooded,
and drop the message if the loop count expires.

B. log the session ID of an outgoing multicast, and drop the message
if the same ID appears in an incoming multicast.

C. throttle the total rate of multicasts.

Here are the things I've discovered while coding a GRASP prototype
in Python:

1. The session ID is (as expected) essential in GRASP negotiation sessions,
since it is the only way for asynchronous outgoing and incoming messages to
rendezvous at the same socket. So it is vital in the following GRASP messages:
M_REQUEST, M_NEGOTIATE, M_WAIT, M_END.

2. The session ID is not essential in a synchronization session
(M_REQUEST followed by M_SYNCH), which doesn't have a rendezvous problem,
but it's harmless and allows for an extra consistency check.

3. The session ID is pretty much useless in M_FLOOD messages, which are
read-only and generate no replies, except for loop prevention (B above).

4. A bit to my surprise, the session ID is also pretty much useless
in discovery (M_DISCOVERY and M_RESPONSE messages), except for loop
prevention. The reason for this is quite complex. In the prototype,
things work as follows:

An ASA calls discover(objective, timeout). Here's
what discover does (simplified):

if the objective is already in the discovery cache:
    return cached locators
else:
    send M_DISCOVER message on each interface
    launch a listener thread for each interface*
    wait (at most) until timeout
    if the objective is now in the discovery cache:
        return cached locators
    else:
        return nothing

Each separate listener thread waits for any M_RESPONSE
replies, and adds them to the cache.

*(yes, I know, in theory one thread can listen to replies from
all interfaces, but I tested it and it didn't work)

The bottom line is that although the M_RESPONSEs will carry
the same Session ID, it is not used in any way.

I don't propose any message format changes because of this, because
I can imagine that another implementation approach might lead to
a different conclusion. Also, the Session ID and source address
might be very useful for debugging problems with relayed messages.

However, I do want to make one small change in the spec as a result
of this. When relaying Discovery, it is *much* easier to generate
a new discovery session than to propagate the incoming one. You'd
have to try coding it to fully understand why. So I want the
rules about relaying to include this: "The relayed message MAY have a
different Session ID."

Any comments? I'd like to post the draft in a few days.

Regards
   Brian

---

From: Brian E Carpenter <[email-masked]>
Date: Sun, 10 Jan 2016 08:17:38 +1300

On 03/01/2016 15:05, Brian E Carpenter wrote:

...
> the same Session ID, it is not used in any way.

I need to correct this. I found an error in the way I handled
listening for M_RESPONSE messages: in fact they all end up
arriving on the same socket for a given interface, and the code
*does* need to demultiplex them using the Session ID.

However this doesn't change anything in the GRASP protocol.

    Brian