GeneRic Autonomic Signaling Protocol (GRASP)
Extracted elements (31)
CBOR (RFC 8949) was chosen as the on-wire encoding because it is readily extensible for unknown future requirements and imposes no practical restriction on objective value formats. The loop count is placed in the objective option (not the message header) because it is semantically a property of the objective itself.
GRASP intentionally has no version number; extensibility is achieved by adding new message types and options. The M_INVALID message signals that an implementation does not recognize a message or option, supporting both forward and backward compatibility detection without a version field.
GRASP uses a simple bilateral (two-party) negotiation model rather than multiparty negotiation because multiparty negotiations are very complicated to model and cannot readily be guaranteed to converge. Multiparty negotiations can be supported by indirect bilateral steps between pairs of ASAs.
GRASP is explicitly designed to operate within a single addressing realm; its discovery and flooding mechanisms do not support operations across address translators or upper-layer proxies. IPv4 locator options MUST NOT be used within Divert options if internal NAT is in use.
Rapid mode (combined M_DISCOVERY + M_REQ_NEG or M_REQ_SYN) SHOULD be disabled by default and MAY be enabled by Intent, because a network with a mix of rapid-mode and non-rapid-mode nodes exhibits complex timing-dependent behaviors. The rapid synchronization function SHOULD be configured off by default.
A new Session ID MUST be generated by the initiator for every new Discovery, Flood Synchronization, or Request message. The Session ID MUST be generated by a PRNG using a locally generated seed; the PRNG SHOULD be cryptographically strong (RFC 4086). GRASP MUST check that a newly allocated Session ID is not already in use.
A node that receives a Request message (M_REQ_NEG or M_REQ_SYN) for an objective for which no ASA is currently listening MUST immediately close the relevant socket. To avoid a race condition with simultaneous sessions, a node MUST verify that the received Session ID is not already locally active; on a clash it MUST discard the Request message.
A relaying GRASP instance MUST support discovery on all GRASP interfaces, MUST decrement the loop count within the objective, and MUST NOT relay a Discovery message if the result is zero. It MUST limit the relay rate to mitigate DoS attacks and MUST cache Session ID and initiator address to prevent loops (must not relay a given Session ID + initiator pair more than once).
All unicast GRASP messages MUST use a reliable transport protocol because GRASP itself does not provide error detection, retransmission, or flow control. Unless otherwise specified by the substrate, TCP MUST be used.
DULL (Discovery Unsolicited Link-Local) GRASP usage MUST be limited to link-local operations on a single interface and MUST be confined to a separate insecure instance of GRASP with its own copy of all data structures. Initiators MAY send Discovery or Flood Synchronization multicasts with loop count of 1; other unsolicited message types MUST NOT be sent.
Every solution adopting GRASP MUST specify a security and transport substrate. The substrate MUST enforce sending and receiving GRASP messages only between members of a mutually trusted group, MUST use cryptographic member authentication and message integrity, and MUST provide mechanisms to remove untrusted members from the group.
Generic objective names MUST NOT include a colon and MUST be registered with IANA. Privately defined objective names MUST include at least one colon, and the string preceding the last colon MUST be globally unique — acceptable methods are a PEN, an FQDN, or an email address.
GRASP nodes MUST be able to receive unicast messages of at least GRASP_DEF_MAX_SIZE (2048) bytes and MUST NOT send unicast messages longer than GRASP_DEF_MAX_SIZE bytes unless a longer size is explicitly allowed for the objective concerned, for example via prior GRASP negotiation.
If the substrate specifies UDP for discovery/flooding, it MUST NOT use IP fragmentation. GRASP MUST then enforce a message size limit at the user API level; for IPv6, multicast packets MUST be at most 1280 bytes unless a known larger minimum link MTU is confirmed across the whole GRASP domain.
The discovery cache MUST include a lifetime for each entry derived from the ttl parameter in Discovery Response messages. Cached entries MUST be ignored or deleted after their lifetime expires. The discovery mechanism needs to track the node's current address to ensure Discovery Responses always indicate the correct address.
The originator of a Flood Synchronization message MUST set the loop count to a suitable value (default GRASP_DEF_LOOPCT). A relaying device MUST decrement the loop count and MUST NOT relay if the result is zero; it MUST limit relay rate and MUST cache Session ID and initiator address for at least 2×GRASP_DEF_TIMEOUT ms to prevent loops.
When sending a Negotiation message (M_NEGOTIATE), the sender MUST include the relevant Negotiation Objective option with its loop count decremented by 1. If the loop count becomes zero, the message MUST NOT be sent and the session has failed. A Request Negotiation message MUST initialize the loop count to the value specified by the objective or GRASP_DEF_LOOPCT.
A GRASP objective option has the structure [objective-name, objective-flags, loop-count, ?objective-value]. The name is a UTF-8 string compared byte by byte; loop-count is 0–255 and controls relay depth and negotiation convergence; objective-value is any CBOR-serializable data.
Every GRASP message except M_NOOP is a CBOR array with the structure [MESSAGE_TYPE, session-id, ?initiator, *grasp-option]. MESSAGE_TYPE is 0–255; session-id is a 32-bit unsigned integer. Options are presented serially. The complete normative definition uses CDDL (RFC 8610).
GRASP constants: ALL_GRASP_NEIGHBORS multicast addresses (ff02::13 IPv6, 224.0.0.119 IPv4); GRASP_LISTEN_PORT 7017 (well-known UDP/TCP port); GRASP_DEF_TIMEOUT 60000 ms; GRASP_DEF_LOOPCT 6; GRASP_DEF_MAX_SIZE 2048 bytes.
GRASP defines 11 message types: M_DISCOVERY, M_RESPONSE (discovery); M_REQ_NEG, M_NEGOTIATE, M_WAIT, M_END (negotiation); M_REQ_SYN, M_SYNCH, M_FLOOD (synchronization); M_NOOP and M_INVALID (housekeeping). Unrecognized types in unicast messages MAY elicit M_INVALID; in multicast they MUST be silently discarded.
IANA registers: GRASP Message Types (the MESSAGE_TYPE field, 0–255); GRASP Option Types (unsigned integers identifying option kinds); and GRASP Objective Names (generic names without colons). Initial values are defined by the CDDL specification in Section 4 of this document.
Discovery and flood relay loops and DoS amplification are mitigated by: decrementing loop counts and dropping at zero; caching and rejecting duplicate Session ID + initiator pairs; and rate-limiting relay output to a small multiple of the observed normal traffic rate.
DULL GRASP is intrinsically insecure and operates without preexisting security associations, making it vulnerable to on-link attackers. It must be confined to link-local scope. Flooded synchronization objectives SHOULD NOT contain unencrypted private information and SHOULD be validated by recipient ASAs.
GRASP has no built-in security and relies entirely on an external security and transport substrate. Any member of the mutually trusted group can attack the entire network until revoked via PKI certificate revocation or expiry. If the substrate does not mandate encryption, services using GRASP MUST provide their own protection for sensitive message elements.
Negotiation state machine: Initiator sends M_REQ_NEG (starts GRASP_DEF_TIMEOUT timer with loop count). Counterpart replies M_NEGOTIATE (loop count decremented, propose alternative) or M_END+O_ACCEPT (immediate accept). Either side may send M_WAIT to extend the timer. Session terminates via M_END+O_ACCEPT, M_END+O_DECLINE, timer expiry, or loop count reaching zero.
Synchronization flow: Initiator sends M_REQ_SYN to a discovered counterpart. Counterpart replies with M_SYNCH containing the current objective value; transport SHOULD be closed afterwards. Alternatively, any node may send unsolicited M_FLOOD to multicast synchronization data; recipients cache flooded objectives tagged with the accompanying locator option.
Objective flags are a CBOR uint bitfield: F_DISC=bit 0 (valid for discovery), F_NEG=bit 1 (valid for negotiation), F_SYNCH=bit 2 (valid for synchronization), F_NEG_DRY=bit 3 (dry-run negotiation). Bits are independent and may be combined; mixing negotiation and dry-run modes in a single session is not allowed.
The Discovery message is encoded as [M_DISCOVERY, session-id, initiator, objective] where 'initiator' is the globally unique IP address of the initiator used solely for Session ID disambiguation. The objective MUST be exactly one of: a Discovery Objective, a Negotiation Objective (rapid mode), or a Synchronization Objective (rapid mode).
The Flood Synchronization message is encoded as [M_FLOOD, session-id, initiator, ttl, +[objective, (locator-option / [])]]. The ttl is in milliseconds; zero indicates indefinite lifetime. Each objective MUST be followed by either a locator option or an empty array (null locator).
The Locator IPv6 Address option is encoded as [O_IPv6_LOCATOR, ipv6-address (bytes .size 16), transport-proto (6=TCP / 17=UDP), port-number (0–65535)]. The IPv6 address MUST have global scope except in DULL GRASP objectives where a link-local address MAY be used; link-local addresses MUST NOT appear inside a Divert option.