summaryrefslogtreecommitdiff
path: root/doc/rfc/rfc8991.txt
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-11-27 20:54:24 +0100
committerThomas Voss <mail@thomasvoss.com> 2024-11-27 20:54:24 +0100
commit4bfd864f10b68b71482b35c818559068ef8d5797 (patch)
treee3989f47a7994642eb325063d46e8f08ffa681dc /doc/rfc/rfc8991.txt
parentea76e11061bda059ae9f9ad130a9895cc85607db (diff)
doc: Add RFC documents
Diffstat (limited to 'doc/rfc/rfc8991.txt')
-rw-r--r--doc/rfc/rfc8991.txt1745
1 files changed, 1745 insertions, 0 deletions
diff --git a/doc/rfc/rfc8991.txt b/doc/rfc/rfc8991.txt
new file mode 100644
index 0000000..80a22d9
--- /dev/null
+++ b/doc/rfc/rfc8991.txt
@@ -0,0 +1,1745 @@
+
+
+
+
+Internet Engineering Task Force (IETF) B. Carpenter
+Request for Comments: 8991 Univ. of Auckland
+Category: Informational B. Liu, Ed.
+ISSN: 2070-1721 Huawei Technologies
+ W. Wang
+ X. Gong
+ BUPT University
+ May 2021
+
+
+ GeneRic Autonomic Signaling Protocol Application Program Interface
+ (GRASP API)
+
+Abstract
+
+ This document is a conceptual outline of an Application Programming
+ Interface (API) for the GeneRic Autonomic Signaling Protocol (GRASP).
+ Such an API is needed for Autonomic Service Agents (ASAs) calling the
+ GRASP protocol module to exchange Autonomic Network messages with
+ other ASAs. Since GRASP is designed to support asynchronous
+ operations, the API will need to be adapted according to the support
+ for asynchronicity in various programming languages and operating
+ systems.
+
+Status of This Memo
+
+ This document is not an Internet Standards Track specification; it is
+ published for informational purposes.
+
+ This document is a product of the Internet Engineering Task Force
+ (IETF). It represents the consensus of the IETF community. It has
+ received public review and has been approved for publication by the
+ Internet Engineering Steering Group (IESG). Not all documents
+ approved by the IESG are candidates for any level of Internet
+ Standard; see Section 2 of RFC 7841.
+
+ Information about the current status of this document, any errata,
+ and how to provide feedback on it may be obtained at
+ https://www.rfc-editor.org/info/rfc8991.
+
+Copyright Notice
+
+ Copyright (c) 2021 IETF Trust and the persons identified as the
+ document authors. All rights reserved.
+
+ This document is subject to BCP 78 and the IETF Trust's Legal
+ Provisions Relating to IETF Documents
+ (https://trustee.ietf.org/license-info) in effect on the date of
+ publication of this document. Please review these documents
+ carefully, as they describe your rights and restrictions with respect
+ to this document. Code Components extracted from this document must
+ include Simplified BSD License text as described in Section 4.e of
+ the Trust Legal Provisions and are provided without warranty as
+ described in the Simplified BSD License.
+
+Table of Contents
+
+ 1. Introduction
+ 2. GRASP API for ASA
+ 2.1. Design Assumptions
+ 2.2. Asynchronous Operations
+ 2.2.1. Alternative Asynchronous Mechanisms
+ 2.2.2. Multiple Negotiation Scenario
+ 2.2.3. Overlapping Sessions and Operations
+ 2.2.4. Session Termination
+ 2.3. API Definition
+ 2.3.1. Overview of Functions
+ 2.3.2. Parameters and Data Structures
+ 2.3.3. Registration
+ 2.3.4. Discovery
+ 2.3.5. Negotiation
+ 2.3.6. Synchronization and Flooding
+ 2.3.7. Invalid Message Function
+ 3. Security Considerations
+ 4. IANA Considerations
+ 5. References
+ 5.1. Normative References
+ 5.2. Informative References
+ Appendix A. Error Codes
+ Acknowledgements
+ Authors' Addresses
+
+1. Introduction
+
+ As defined in [RFC8993], the Autonomic Service Agent (ASA) is the
+ atomic entity of an autonomic function, and it is instantiated on
+ autonomic nodes. These nodes are members of a secure Autonomic
+ Control Plane (ACP) such as defined by [RFC8994].
+
+ When ASAs communicate with each other, they should use the GeneRic
+ Autonomic Signaling Protocol (GRASP) [RFC8990]. GRASP relies on the
+ message confidentiality and integrity provided by the ACP; a
+ consequence of this is that all nodes in a given Autonomic Network
+ share the same trust boundary, i.e., the boundary of the ACP. Nodes
+ that have not successfully joined the ACP cannot send, receive, or
+ intercept GRASP messages via the ACP and cannot usurp ACP addresses.
+ An ASA runs in an ACP node and therefore benefits from the node's
+ security properties when transmitting over the ACP, i.e., message
+ integrity, message confidentiality, and the fact that unauthorized
+ nodes cannot join the ACP. All ASAs within a given Autonomic Network
+ therefore trust each other's messages. For these reasons, the API
+ defined in this document has no explicit security features.
+
+ An important feature of GRASP is the concept of a GRASP objective.
+ This is a data structure encoded, like all GRASP messages, in Concise
+ Binary Object Representation (CBOR) [RFC8949]. Its main contents are
+ a name and a value, explained at more length in the Terminology
+ section of [RFC8990]. When an objective is passed from one ASA to
+ another using GRASP, its value is either conveyed in one direction
+ (by a process of synchronization or flooding) or negotiated
+ bilaterally. The semantics of the value are opaque to GRASP and
+ therefore to the API. Each objective must be accurately specified in
+ a dedicated specification, as discussed in "Objective Options"
+ (Section 2.10 of [RFC8990]). In particular, the specification will
+ define the syntax and semantics of the value of the objective,
+ whether and how it supports a negotiation process, whether it
+ supports a dry-run mode, and any other details needed for
+ interoperability. The use of CBOR, with Concise Data Definition
+ Language (CDDL) [RFC8610] as the data definition language, allows the
+ value to be passed between ASAs regardless of the programming
+ languages in use. Data storage and consistency during negotiation
+ are the responsibility of the ASAs involved. Additionally, GRASP
+ needs to cache the latest values of objectives that are received by
+ flooding.
+
+ As Figure 1 shows, a GRASP implementation could contain several sub-
+ layers. The bottom layer is the GRASP base protocol module, which is
+ only responsible for sending and receiving GRASP messages and
+ maintaining shared data structures. Above that is the basic API
+ described in this document. The upper layer contains some extended
+ API functions based upon the GRASP basic protocol. For example,
+ [GRASP-DISTRIB] describes a possible extended function.
+
+ +--------------+ +--------------+
+ | ASAs | | ASAs |
+ +--------------+ +--------------+
+ | | |
+ | +------------------+ |
+ | | GRASP Extended | |
+ | | Function API | |
+ | +------------------+ |
+ | | |
+ +------------------------------------------+
+ | Basic GRASP API Library |
+ +------------------------------------------+
+ |
+ IPC or system call
+ |
+ +------------------------------------------+
+ | GRASP Core |
+ | (functions, data structures, daemon(s)) |
+ +------------------------------------------+
+
+ Figure 1: Software Layout
+
+ Multiple ASAs in a single node will share the same instance of GRASP,
+ much as multiple applications share a single TCP/IP stack. This
+ aspect is hidden from individual ASAs by the API and is not further
+ discussed here.
+
+ It is desirable that ASAs be designed as portable user-space programs
+ using a system-independent API. In many implementations, the GRASP
+ code will therefore be split between user space and kernel space. In
+ user space, library functions provide the API and communicate
+ directly with ASAs. In kernel space, a daemon, or a set of sub-
+ services, provides GRASP core functions that are independent of
+ specific ASAs, such as multicast handling and relaying, and common
+ data structures, such as the discovery cache. The GRASP API library
+ would need to communicate with the GRASP core via an interprocess
+ communication (IPC) or a system call mechanism. The details of this
+ are system-dependent.
+
+ Both the GRASP library and the extended function modules should be
+ available to the ASAs. However, since the extended functions are
+ expected to be added in an incremental manner, they will be the
+ subject of future documents. This document only describes the basic
+ GRASP API.
+
+ The functions provided by the API do not map one-to-one onto GRASP
+ messages. Rather, they are intended to offer convenient support for
+ message sequences (such as a discovery request followed by responses
+ from several peers or a negotiation request followed by various
+ possible responses). This choice was made to assist ASA programmers
+ in writing code based on their application requirements rather than
+ needing to understand protocol details.
+
+ In addition to containing the autonomic infrastructure components
+ described in [RFC8994] and [RFC8995], a simple autonomic node might
+ contain very few ASAs. Such a node might directly integrate a GRASP
+ protocol stack in its code and therefore not require this API to be
+ installed. However, the programmer would need a deeper understanding
+ of the GRASP protocol than what is needed to use the API.
+
+ This document gives a conceptual outline of the API. It is not a
+ formal specification for any particular programming language or
+ operating system, and it is expected that details will be clarified
+ in individual implementations.
+
+2. GRASP API for ASA
+
+2.1. Design Assumptions
+
+ The design assumes that an ASA needs to call a separate GRASP
+ implementation. The latter handles protocol details (security,
+ sending and listening for GRASP messages, waiting, caching discovery
+ results, negotiation looping, sending and receiving synchronization
+ data, etc.) but understands nothing about individual GRASP objectives
+ (see Section 2.10 of [RFC8990]). The semantics of objectives are
+ unknown to the GRASP protocol and are handled only by the ASAs.
+ Thus, this is an abstract API for use by ASAs. Individual language
+ bindings should be defined in separate documents.
+
+ Different ASAs may utilize GRASP features differently, by using GRASP
+ for:
+
+ * discovery purposes only.
+
+ * negotiation but only as an initiator (client).
+
+ * negotiation but only as a responder.
+
+ * negotiation as an initiator or responder.
+
+ * synchronization but only as an initiator (recipient).
+
+ * synchronization but only as a responder and/or flooder.
+
+ * synchronization as an initiator, responder, and/or flooder.
+
+ The API also assumes that one ASA may support multiple objectives.
+ Nothing prevents an ASA from supporting some objectives for
+ synchronization and others for negotiation.
+
+ The API design assumes that the operating system and programming
+ language provide a mechanism for simultaneous asynchronous
+ operations. This is discussed in detail in Section 2.2.
+
+ A few items are out of scope in this version, since practical
+ experience is required before including them:
+
+ * Authorization of ASAs is not defined as part of GRASP and is a
+ subject for future study.
+
+ * User-supplied explicit locators for an objective are not
+ supported. The GRASP core will supply the locator, using the IP
+ address of the node concerned.
+
+ * The rapid mode of GRASP (Section 2.5.4 of [RFC8990]) is not
+ supported.
+
+2.2. Asynchronous Operations
+
+ GRASP depends on asynchronous operations and wait states, and some of
+ its messages are not idempotent, meaning that repeating a message may
+ cause repeated changes of state in the recipient ASA. Many ASAs will
+ need to support several concurrent operations; for example, an ASA
+ might need to negotiate one objective with a peer while discovering
+ and synchronizing a different objective with a different peer.
+ Alternatively, an ASA that acts as a resource manager might need to
+ run simultaneous negotiations for a given objective with multiple
+ different peers. Such an ASA will probably need to support
+ uninterruptible atomic changes to its internal data structures, using
+ a mechanism provided by the operating system and programming language
+ in use.
+
+2.2.1. Alternative Asynchronous Mechanisms
+
+ Some ASAs need to support asynchronous operations; therefore, the
+ GRASP core must do so. Depending on both the operating system and
+ the programming language in use, there are various techniques for
+ such parallel operations, three of which we consider here:
+ multithreading, an event loop structure using polling, and an event
+ loop structure using callback functions.
+
+ 1. In multithreading, the operating system and language will provide
+ the necessary support for asynchronous operations, including
+ creation of new threads, context switching between threads,
+ queues, locks, and implicit wait states. In this case, API calls
+ can be treated as simple synchronous function calls within their
+ own thread, even if the function includes wait states, blocking,
+ and queueing. Concurrent operations will each run in their own
+ threads. For example, the discover() call may not return until
+ discovery results have arrived or a timeout has occurred. If the
+ ASA has other work to do, the discover() call must be in a thread
+ of its own.
+
+ 2. In an event loop implementation with polling, blocking calls are
+ not acceptable. Therefore, all calls must be non-blocking, and
+ the main loop could support multiple GRASP sessions in parallel
+ by repeatedly polling each one for a change of state. To
+ facilitate this, the API implementation would provide non-
+ blocking versions of all the functions that otherwise involve
+ blocking and queueing. In these calls, a 'noReply' code will be
+ returned by each call instead of blocking, until such time as the
+ event for which it is waiting (or a failure) has occurred. Thus,
+ for example, discover() would return 'noReply' instead of waiting
+ until discovery has succeeded or timed out. The discover() call
+ would be repeated in every cycle of the main loop until it
+ completes. Effectively, it becomes a polling call.
+
+ 3. It was noted earlier that some GRASP messages are not idempotent;
+ in particular, this applies to each step in a negotiation session
+ -- sending the same message twice might produce unintended side
+ effects. This is not affected by event loop polling: repeating a
+ call after a 'noReply' does not repeat a message; it simply
+ checks whether a reply has been received.
+
+ 4. In an event loop implementation with callbacks, the ASA
+ programmer would provide a callback function for each
+ asynchronous operation. This would be called asynchronously when
+ a reply is received or a failure such as a timeout occurs.
+
+2.2.2. Multiple Negotiation Scenario
+
+ The design of GRASP allows the following scenario. Consider an ASA
+ "A" that acts as a resource allocator for some objective. An ASA "B"
+ launches a negotiation with "A" to obtain or release a quantity of
+ the resource. While this negotiation is under way, "B" chooses to
+ launch a second simultaneous negotiation with "A" for a different
+ quantity of the same resource. "A" must therefore conduct two
+ separate negotiation sessions at the same time with the same peer and
+ must not mix them up.
+
+ Note that ASAs could be designed to avoid such a scenario, i.e.,
+ restricted to exactly one negotiation session at a time for a given
+ objective, but this would be a voluntary restriction not required by
+ the GRASP protocol. In fact, GRASP assumes that any ASA managing a
+ resource may need to conduct multiple parallel negotiations, possibly
+ with the same peer. Communication patterns could be very complex,
+ with a group of ASAs overlapping negotiations among themselves, as
+ described in [ANIMA-COORD]. Therefore, the API design allows for
+ such scenarios.
+
+ In the callback model, for the scenario just described, the ASAs "A"
+ and "B" will each provide two instances of the callback function, one
+ for each session. For this reason, each ASA must be able to
+ distinguish the two sessions, and the peer's IP address is not
+ sufficient for this. It is also not safe to rely on transport port
+ numbers for this, since future variants of GRASP might use shared
+ ports rather than a separate port per session. Hence, the GRASP
+ design includes a Session ID. Thus, when necessary, a session handle
+ (see the next section) is used in the API to distinguish simultaneous
+ GRASP sessions from each other, so that any number of sessions may
+ proceed asynchronously in parallel.
+
+2.2.3. Overlapping Sessions and Operations
+
+ A GRASP session consists of a finite sequence of messages (for
+ discovery, synchronization, or negotiation) between two ASAs. It is
+ uniquely identified on the wire by a pseudorandom Session ID plus the
+ IP address of the initiator of the session. Further details are
+ given in "Session Identifier (Session ID)" (Section 2.7 of
+ [RFC8990]).
+
+ On the first call in a new GRASP session, the API returns a
+ 'session_handle' handle that uniquely identifies the session within
+ the API, so that multiple overlapping sessions can be distinguished.
+ A likely implementation is to form the handle from the underlying
+ GRASP Session ID and IP address. This handle must be used in all
+ subsequent calls for the same session. Also see Section 2.3.2.8.
+
+ An additional mechanism that might increase efficiency for polling
+ implementations is to add a general call, say notify(), which would
+ check the status of all outstanding operations for the calling ASA
+ and return the session_handle values for all sessions that have
+ changed state. This would eliminate the need for repeated calls to
+ the individual functions returning a 'noReply'. This call is not
+ described below as the details are likely to be implementation
+ specific.
+
+ An implication of the above for all GRASP implementations is that the
+ GRASP core must keep state for each GRASP operation in progress, most
+ likely keyed by the GRASP Session ID and the GRASP source address of
+ the session initiator. Even in a threaded implementation, the GRASP
+ core will need such state internally. The session_handle parameter
+ exposes this aspect of the implementation.
+
+2.2.4. Session Termination
+
+ GRASP sessions may terminate for numerous reasons. A session ends
+ when discovery succeeds or times out, negotiation succeeds or fails,
+ a synchronization result is delivered, the other end fails to respond
+ before a timeout expires, a loop count expires, or a network socket
+ error occurs. Note that a timeout at one end of a session might
+ result in a timeout or a socket error at the other end, since GRASP
+ does not send error messages in this case. In all cases, the API
+ will return an appropriate code to the caller, which should then
+ release any reserved resources. After failure cases, the GRASP
+ specification recommends an exponential backoff before retrying.
+
+2.3. API Definition
+
+2.3.1. Overview of Functions
+
+ The functions provided by the API fall into several groups:
+
+ Registration: These functions allow an ASA to register itself with
+ the GRASP core and allow a registered ASA to register the GRASP
+ objectives that it will manipulate.
+
+ Discovery: This function allows an ASA that needs to initiate
+ negotiation or synchronization of a particular objective to
+ discover a peer willing to respond.
+
+ Negotiation: These functions allow an ASA to act as an initiator
+ (requester) or responder (listener) for a GRASP negotiation
+ session. After initiation, negotiation is a symmetric process, so
+ most of the functions can be used by either party.
+
+ Synchronization: These functions allow an ASA to act as an initiator
+ (requester) or responder (listener and data source) for a GRASP
+ synchronization session.
+
+ Flooding: These functions allow an ASA to send and receive an
+ objective that is flooded to all nodes of the ACP.
+
+ Some example logic flows for a resource management ASA are given in
+ [ASA-GUIDE], which may be of help in understanding the following
+ descriptions. The next section describes parameters and data
+ structures used in multiple API calls. The following sections
+ describe various groups of function APIs. Those APIs that do not
+ list asynchronous mechanisms are implicitly synchronous in their
+ behavior.
+
+2.3.2. Parameters and Data Structures
+
+2.3.2.1. Integers
+
+ In this API, integers are assumed to be 32-bit unsigned integers
+ (uint32_t) unless otherwise indicated.
+
+2.3.2.2. Errorcode
+
+ All functions in the API have an unsigned 'errorcode' integer as
+ their return value (the first return value in languages that allow
+ multiple return values). An errorcode of zero indicates success.
+ Any other value indicates failure of some kind. The first three
+ errorcodes have special importance:
+
+ 1 - Declined: used to indicate that the other end has sent a GRASP
+ Negotiation End message (M_END) with a Decline option (O_DECLINE).
+
+ 2 - No reply: used in non-blocking calls to indicate that the other
+ end has sent no reply so far (see Section 2.2).
+
+ 3 - Unspecified error: used when no more specific error codes apply.
+
+ Appendix A gives a full list of currently suggested error codes,
+ based on implementation experience. While there is no absolute
+ requirement for all implementations to use the same error codes, this
+ is highly recommended for portability of applications.
+
+2.3.2.3. Timeout
+
+ Whenever a 'timeout' parameter appears, it is an unsigned integer
+ expressed in milliseconds. If it is zero, the GRASP default timeout
+ (GRASP_DEF_TIMEOUT; see [RFC8990]) will apply. An exception is the
+ discover() function, which has a different interpretation of a zero
+ timeout. If no response is received before the timeout expires, the
+ call will fail unless otherwise noted.
+
+2.3.2.4. Objective
+
+ An 'objective' parameter is a data structure with the following
+ components:
+
+ name (UTF-8 string): The objective's name
+
+ neg (Boolean flag): True if objective supports negotiation (default
+ False)
+
+ synch (Boolean flag): True if objective supports synchronization
+ (default False)
+
+ dry (Boolean flag): True if objective supports dry-run negotiation
+ (default False)
+
+ Note 1: Only one of 'synch' or 'neg' may be True.
+ Note 2: 'dry' must not be True unless 'neg' is also True.
+ Note 3: In some programming languages, the preferred
+ implementation may be to represent the Boolean flags as bits in
+ a single byte, which is how they are encoded in GRASP messages.
+ In other languages, an enumeration might be preferable.
+
+ loop_count (unsigned integer, uint8_t): Limit on negotiation steps,
+ etc. (default GRASP_DEF_LOOPCT; see [RFC8990]). The 'loop_count'
+ is set to a suitable value by the initiator of a negotiation, to
+ prevent indefinite loops. It is also used to limit the
+ propagation of discovery and flood messages.
+
+ value: A specific data structure expressing the value of the
+ objective. The format is language dependent, with the constraint
+ that it can be validly represented in CBOR [RFC8949].
+
+ An important advantage of CBOR is that the value of an
+ objective can be completely opaque to the GRASP core yet pass
+ transparently through it to and from the ASA. Although the
+ GRASP core must validate the format and syntax of GRASP
+ messages, it cannot validate the value of an objective; all it
+ can do is detect malformed CBOR. The handling of decoding
+ errors depends on the CBOR library in use, but a corresponding
+ error code ('CBORfail') is defined in the API and will be
+ returned to the ASA if a faulty message can be assigned to a
+ current GRASP session. However, it is the responsibility of
+ each ASA to validate the value of a received objective, as
+ discussed in Section 5.3 of [RFC8949]. If the programming
+ language in use is suitably object-oriented, the GRASP API may
+ deserialize the value and present it to the ASA as an object.
+ If not, it will be presented as a CBOR data item. In all
+ cases, the syntax and semantics of the objective value are the
+ responsibility of the ASA.
+
+ A requirement for all language mappings and all API
+ implementations is that, regardless of what other options exist
+ for a language-specific representation of the value, there is
+ always an option to use a raw CBOR data item as the value. The
+ API will then wrap this with CBOR Tag 24 as an encoded CBOR
+ data item for transmission via GRASP, and unwrap it after
+ reception. By this means, ASAs will be able to communicate
+ regardless of programming language.
+
+ The 'name' and 'value' fields are of variable length. GRASP does not
+ set a maximum length for these fields, but only for the total length
+ of a GRASP message. Implementations might impose length limits.
+
+ An example data structure definition for an objective in the C
+ language, using at least the C99 version, and assuming the use of a
+ particular CBOR library [libcbor], is:
+
+ typedef struct {
+ unsigned char *name;
+ uint8_t flags; // flag bits as defined by GRASP
+ uint8_t loop_count;
+ uint32_t value_size; // size of value in bytes
+ cbor_mutable_data cbor_value;
+ // CBOR bytestring (libcbor/cbor/data.h)
+ } objective;
+
+ An example data structure definition for an objective in the Python
+ language (version 3.4 or later) is:
+
+ class objective:
+ """A GRASP objective"""
+ def __init__(self, name):
+ self.name = name #Unique name (string)
+ self.negotiate = False #True if negotiation supported
+ self.dryrun = False #True if dry-run supported
+ self.synch = False #True if synchronization supported
+ self.loop_count = GRASP_DEF_LOOPCT # Default starting value
+ self.value = None #Place holder; any Python object
+
+2.3.2.5. asa_locator
+
+ An 'asa_locator' parameter is a data structure with the following
+ contents:
+
+ locator: The actual locator, either an IP address or an ASCII
+ string.
+
+ ifi (unsigned integer): The interface identifier index via which
+ this was discovered (of limited use to most ASAs).
+
+ expire (system dependent type): The time on the local system clock
+ when this locator will expire from the cache.
+
+ The following covers all locator types currently supported by
+ GRASP:
+ * is_ipaddress (Boolean) - True if the locator is an IP address.
+
+ * is_fqdn (Boolean) - True if the locator is a Fully Qualified
+ Domain Name (FQDN).
+
+ * is_uri (Boolean) - True if the locator is a URI.
+
+ These options are mutually exclusive. Depending on the
+ programming language, they could be represented as a bit pattern
+ or an enumeration.
+
+ diverted (Boolean): True if the locator was discovered via a Divert
+ option.
+
+ protocol (unsigned integer): Applicable transport protocol
+ (IPPROTO_TCP or IPPROTO_UDP). These constants are defined in the
+ CDDL specification of GRASP [RFC8990].
+
+ port (unsigned integer): Applicable port number.
+
+ The 'locator' field is of variable length in the case of an FQDN or a
+ URI. GRASP does not set a maximum length for this field, but only
+ for the total length of a GRASP message. Implementations might
+ impose length limits.
+
+ It should be noted that when one ASA discovers the asa_locator of
+ another, there is no explicit authentication mechanism. In
+ accordance with the trust model provided by the secure ACP, ASAs are
+ presumed to provide correct locators in response to discovery. See
+ "Locator Options" (Section 2.9.5 of [RFC8990]) for further details.
+
+2.3.2.6. Tagged_objective
+
+ A 'tagged_objective' parameter is a data structure with the following
+ contents:
+
+ objective: An objective.
+
+ locator: The asa_locator associated with the objective, or a null
+ value.
+
+2.3.2.7. asa_handle
+
+ Although an authentication and authorization scheme for ASAs has not
+ been defined, the API provides a very simple hook for such a scheme.
+ When an ASA starts up, it registers itself with the GRASP core, which
+ provides it with an opaque handle that, although not
+ cryptographically protected, would be difficult for a third party to
+ predict. The ASA must present this handle in future calls. This
+ mechanism will prevent some elementary errors or trivial attacks such
+ as an ASA manipulating an objective it has not registered to use.
+
+ Thus, in most calls, an 'asa_handle' parameter is required. It is
+ generated when an ASA first registers with GRASP, and the ASA must
+ then store the asa_handle and use it in every subsequent GRASP call.
+ Any call in which an invalid handle is presented will fail. It is an
+ up to 32-bit opaque value (for example, represented as a uint32_t,
+ depending on the language). Since it is only used locally, and not
+ in GRASP messages, it is only required to be unique within the local
+ GRASP instance. It is valid until the ASA terminates. It should be
+ unpredictable; a possible implementation is to use the same mechanism
+ that GRASP uses to generate Session IDs (see Section 2.3.2.8).
+
+2.3.2.8. Session_handle and Callbacks
+
+ In some calls, a 'session_handle' parameter is required. This is an
+ opaque data structure as far as the ASA is concerned, used to
+ identify calls to the API as belonging to a specific GRASP session
+ (see Section 2.2.3). It will be provided as a parameter in callback
+ functions. As well as distinguishing calls from different sessions,
+ it also allows GRASP to detect and ignore calls from non-existent or
+ timed-out sessions.
+
+ In an event loop implementation, callback functions (Section 2.2.1)
+ may be supported for all API functions that involve waiting for a
+ remote operation:
+
+ discover() whose callback would be discovery_received().
+
+ request_negotiate() whose callback would be
+ negotiate_step_received().
+
+ negotiate_step() whose callback would be
+ negotiate_step_received().
+
+ listen_negotiate() whose callback would be
+ negotiate_step_received().
+
+ synchronize() whose callback would be synchronization_received().
+
+ Further details of callbacks are implementation dependent.
+
+2.3.3. Registration
+
+ These functions are used to register an ASA, and the objectives that
+ it modifies, with the GRASP module. In the absence of an
+ authorization model, these functions are very simple, but they will
+ avoid multiple ASAs choosing the same name and will prevent multiple
+ ASAs manipulating the same objective. If an authorization model is
+ added to GRASP, these API calls would need to be modified
+ accordingly.
+
+ * register_asa()
+
+ All ASAs must use this call before issuing any other API calls.
+
+ - Input parameter:
+
+ name of the ASA (UTF-8 string)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ asa_handle (unsigned integer)
+
+ - This initializes the state in the GRASP module for the calling
+ entity (the ASA). In the case of success, an 'asa_handle' is
+ returned, which the ASA must present in all subsequent calls.
+ In the case of failure, the ASA has not been authorized and
+ cannot operate. The 'asa_handle' value is undefined.
+
+ * deregister_asa()
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ name of the ASA (UTF-8 string)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - This removes all state in the GRASP module for the calling
+ entity (the ASA) and deregisters any objectives it has
+ registered. Note that these actions must also happen
+ automatically if an ASA exits.
+
+ - Note -- the ASA name is, strictly speaking, redundant in this
+ call but is present to detect and reject erroneous
+ deregistrations.
+
+ * register_objective()
+
+ ASAs must use this call for any objective whose value they need to
+ transmit by negotiation, synchronization, or flooding.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ objective (structure)
+
+ ttl (unsigned integer -- default GRASP_DEF_TIMEOUT)
+
+ discoverable (Boolean -- default False)
+
+ overlap (Boolean -- default False)
+
+ local (Boolean -- default False)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - This registers an objective that this ASA may modify and
+ transmit to other ASAs by flooding or negotiation. It is not
+ necessary to register an objective that is only received by
+ GRASP synchronization or flooding. The 'objective' becomes a
+ candidate for discovery. However, discovery responses should
+ not be enabled until the ASA calls listen_negotiate() or
+ listen_synchronize(), showing that it is able to act as a
+ responder. The ASA may negotiate the objective or send
+ synchronization or flood data. Registration is not needed for
+ "read-only" operations, i.e., the ASA only wants to receive
+ synchronization or flooded data for the objective concerned.
+
+ - The 'ttl' parameter is the valid lifetime (time to live) in
+ milliseconds of any discovery response generated for this
+ objective. The default value should be the GRASP default
+ timeout (GRASP_DEF_TIMEOUT; see [RFC8990]).
+
+ - If the parameter 'discoverable' is True, the objective is
+ immediately discoverable. This is intended for objectives that
+ are only defined for GRASP discovery and that do not support
+ negotiation or synchronization.
+
+ - If the parameter 'overlap' is True, more than one ASA may
+ register this objective in the same GRASP instance. This is of
+ value for life cycle management of ASAs [ASA-GUIDE] and must be
+ used consistently for a given objective (always True or always
+ False).
+
+ - If the parameter 'local' is True, discovery must return a link-
+ local address. This feature is for objectives that must be
+ restricted to the local link.
+
+ - This call may be repeated for multiple objectives.
+
+ * deregister_objective()
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ objective (structure)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - The 'objective' must have been registered by the calling ASA;
+ if not, this call fails. Otherwise, it removes all state in
+ the GRASP module for the given objective.
+
+2.3.4. Discovery
+
+ * discover()
+
+ This function may be used by any ASA to discover peers handling a
+ given objective.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ objective (structure)
+
+ timeout (unsigned integer)
+
+ minimum_TTL (unsigned integer)
+
+ - Return values:
+
+ errorcode (unsigned integer)
+
+ locator_list (structure)
+
+ - This returns a list of discovered 'asa_locators' for the given
+ objective. An empty list means that no locators were
+ discovered within the timeout. Note that this structure
+ includes all the fields described in Section 2.3.2.5.
+
+ - The parameter 'minimum_TTL' must be greater than or equal to
+ zero. Any locally cached locators for the objective whose
+ remaining time to live in milliseconds is less than or equal to
+ 'minimum_TTL' are deleted first. Thus, 'minimum_TTL' = 0 will
+ flush all entries. Note that this will not affect sessions
+ already in progress using the deleted locators.
+
+ - If the parameter 'timeout' is zero, any remaining locally
+ cached locators for the objective are returned immediately, and
+ no other action is taken. (Thus, a call with 'minimum_TTL' and
+ 'timeout' both equal to zero is pointless.)
+
+ - If the parameter 'timeout' is greater than zero, GRASP
+ discovery is performed, and all results obtained before the
+ timeout in milliseconds expires are returned. If no results
+ are obtained, an empty list is returned after the timeout.
+ That is not an error condition. GRASP discovery is not a
+ deterministic process. If there are multiple nodes handling an
+ objective, none, some, or all of them will be discovered before
+ the timeout expires.
+
+ - Asynchronous Mechanisms:
+
+ Threaded implementation: This should be called in a separate
+ thread if asynchronous operation is required.
+
+ Event loop implementation: An additional in/out
+ 'session_handle' parameter is used. If the 'errorcode'
+ parameter has the value 2 ('noReply'), no response has been
+ received so far. The 'session_handle' parameter must be
+ presented in subsequent calls. A callback may be used in
+ the case of a non-zero timeout.
+
+2.3.5. Negotiation
+
+ Since the negotiation mechanism is different from a typical client/
+ server exchange, Figure 2 illustrates the sequence of calls and GRASP
+ messages in a negotiation. Note that after the first protocol
+ exchange, the process is symmetrical, with negotiating steps strictly
+ alternating between the two sides. Either side can end the
+ negotiation. Also, the side that is due to respond next can insert a
+ delay at any time, to extend the other side's timeout. This would be
+ used, for example, if an ASA needed to negotiate with a third party
+ before continuing with the current negotiation.
+
+ The loop count embedded in the objective that is the subject of
+ negotiation is initialized by the ASA that starts a negotiation and
+ is then decremented by the GRASP core at each step, prior to sending
+ each M_NEGOTIATE message. If it reaches zero, the negotiation will
+ fail, and each side will receive an error code.
+
+Initiator Responder
+--------- ---------
+
+ listen_negotiate() \ Await request
+
+request_negotiate()
+ M_REQ_NEG -> negotiate_step() \ Open session,
+ <- M_NEGOTIATE / start negotiation
+negotiate_step()
+ M_NEGOTIATE -> negotiate_step() \ Continue
+ <- M_NEGOTIATE / negotiation
+ ...
+negotiate_wait() \ Insert
+ M_WAIT -> / delay
+negotiate_step()
+ M_NEGOTIATE -> negotiate_step() \ Continue
+ <- M_NEGOTIATE / negotiation
+negotiate_step()
+ M_NEGOTIATE -> end_negotiate() \ End
+ <- M_END / negotiation
+
+ \ Process results
+
+ Figure 2: Negotiation Sequence
+
+ As the negotiation proceeds, each side will update the value of the
+ objective in accordance with its particular semantics, defined in the
+ specification of the objective. Although many objectives will have
+ values that can be ordered, so that negotiation can be a simple
+ bidding process, it is not a requirement.
+
+ Failure to agree, a timeout, or loop count exhaustion may all end a
+ negotiation session, but none of these cases are protocol failures.
+
+ * request_negotiate()
+
+ This function is used by any ASA to initiate negotiation of a
+ GRASP objective as a requester (client).
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ objective (structure)
+
+ peer (asa_locator)
+
+ timeout (unsigned integer)
+
+ - Return values:
+
+ errorcode (unsigned integer)
+
+ session_handle (structure) (undefined unless successful)
+
+ proffered_objective (structure) (undefined unless
+ successful)
+
+ reason (string) (empty unless negotiation declined)
+
+ - This function opens a negotiation session between two ASAs.
+ Note that GRASP currently does not support multiparty
+ negotiation, which would need to be added as an extended
+ function.
+
+ - The 'objective' parameter must include the requested value, and
+ its loop count should be set to a suitable starting value by
+ the ASA. If not, the GRASP default will apply.
+
+ - Note that a given negotiation session may or may not be a dry-
+ run negotiation; the two modes must not be mixed in a single
+ session.
+
+ - The 'peer' parameter is the target node; it must be an
+ 'asa_locator' as returned by discover(). If 'peer' is null,
+ GRASP discovery is automatically performed first to find a
+ suitable peer (i.e., any node that supports the objective in
+ question).
+
+ - The 'timeout' parameter is described in Section 2.3.2.3.
+
+ - If the 'errorcode' return value is 0, the negotiation has
+ successfully started. There are then two cases:
+
+ 1. The 'session_handle' parameter is null. In this case, the
+ negotiation has succeeded with one exchange of messages,
+ and the peer has accepted the request. The returned
+ 'proffered_objective' contains the value accepted by the
+ peer, which is therefore equal to the value in the
+ requested 'objective'. For this reason, no session handle
+ is needed, since the session has ended.
+
+ 2. The 'session_handle' parameter is not null. In this case,
+ negotiation must continue. The 'session_handle' must be
+ presented in all subsequent negotiation steps. The
+ returned 'proffered_objective' contains the first value
+ proffered by the negotiation peer in the first exchange of
+ messages; in other words, it is a counter-offer. The
+ contents of this instance of the objective must be used to
+ prepare the next negotiation step (see negotiate_step()
+ below) because it contains the updated loop count, sent by
+ the negotiation peer. The GRASP code automatically
+ decrements the loop count by 1 at each step and returns an
+ error if it becomes zero. Since this terminates the
+ negotiation, the other end will experience a timeout, which
+ will terminate the other end of the session.
+
+ This function must be followed by calls to 'negotiate_step'
+ and/or 'negotiate_wait' and/or 'end_negotiate' until the
+ negotiation ends. 'request_negotiate' may then be called
+ again to start a new negotiation.
+
+ - If the 'errorcode' parameter has the value 1 ('declined'), the
+ negotiation has been declined by the peer (M_END and O_DECLINE
+ features of GRASP). The 'reason' string is then available for
+ information and diagnostic use, but it may be a null string.
+ For this and any other error code, an exponential backoff is
+ recommended before any retry (see Section 3).
+
+ - Asynchronous Mechanisms:
+
+ Threaded implementation: This should be called in a separate
+ thread if asynchronous operation is required.
+
+ Event loop implementation: The 'session_handle' parameter is
+ used to distinguish multiple simultaneous sessions. If the
+ 'errorcode' parameter has the value 2 ('noReply'), no
+ response has been received so far. The 'session_handle'
+ parameter must be presented in subsequent calls.
+
+ - Use of dry-run mode must be consistent within a GRASP session.
+ The state of the 'dry' flag in the initial request_negotiate()
+ call must be the same in all subsequent negotiation steps of
+ the same session. The semantics of the dry-run mode are built
+ into the ASA; GRASP merely carries the flag bit.
+
+ - Special note for the ACP infrastructure ASA: It is likely that
+ this ASA will need to discover and negotiate with its peers in
+ each of its on-link neighbors. It will therefore need to know
+ not only the link-local IP address but also the physical
+ interface and transport port for connecting to each neighbor.
+ One implementation approach to this is to include these details
+ in the 'session_handle' data structure, which is opaque to
+ normal ASAs.
+
+ * listen_negotiate()
+
+ This function is used by an ASA to start acting as a negotiation
+ responder (listener) for a given GRASP objective.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ objective (structure)
+
+ - Return values:
+
+ errorcode (unsigned integer)
+
+ session_handle (structure) (undefined unless successful)
+
+ requested_objective (structure) (undefined unless
+ successful)
+
+ - This function instructs GRASP to listen for negotiation
+ requests for the given 'objective'. It also enables discovery
+ responses for the objective, as mentioned under
+ register_objective() in Section 2.3.3.
+
+ - Asynchronous Mechanisms:
+
+ Threaded implementation: It will block waiting for an incoming
+ request, so it should be called in a separate thread if
+ asynchronous operation is required. Unless there is an
+ unexpected failure, this call only returns after an incoming
+ negotiation request. If the ASA supports multiple
+ simultaneous transactions, a new sub-thread must be spawned
+ for each new session, so that listen_negotiate() can be
+ called again immediately.
+
+ Event loop implementation: A 'session_handle' parameter is
+ used to distinguish individual sessions. If the ASA
+ supports multiple simultaneous transactions, a new event
+ must be inserted in the event loop for each new session, so
+ that listen_negotiate() can be reactivated immediately.
+
+ - This call only returns (threaded model) or triggers (event
+ loop) after an incoming negotiation request. When this occurs,
+ 'requested_objective' contains the first value requested by the
+ negotiation peer. The contents of this instance of the
+ objective must be used in the subsequent negotiation call
+ because it contains the loop count sent by the negotiation
+ peer. The 'session_handle' must be presented in all subsequent
+ negotiation steps.
+
+ - This function must be followed by calls to 'negotiate_step'
+ and/or 'negotiate_wait' and/or 'end_negotiate' until the
+ negotiation ends.
+
+ - If an ASA is capable of handling multiple negotiations
+ simultaneously, it may call 'listen_negotiate' simultaneously
+ from multiple threads, or insert multiple events. The API and
+ GRASP implementation must support re-entrant use of the
+ listening state and the negotiation calls. Simultaneous
+ sessions will be distinguished by the threads or events
+ themselves, the GRASP session handles, and the underlying
+ unicast transport sockets.
+
+ * stop_listen_negotiate()
+
+ This function is used by an ASA to stop acting as a responder
+ (listener) for a given GRASP objective.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ objective (structure)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - Instructs GRASP to stop listening for negotiation requests for
+ the given objective, i.e., cancels 'listen_negotiate'.
+
+ - Asynchronous Mechanisms:
+
+ Threaded implementation: Must be called from a different
+ thread than 'listen_negotiate'.
+
+ Event loop implementation: No special considerations.
+
+ * negotiate_step()
+
+ This function is used by either ASA in a negotiation session to
+ make the next step in negotiation.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ session_handle (structure)
+
+ objective (structure)
+
+ timeout (unsigned integer) as described in Section 2.3.2.3
+
+ - Return values:
+
+ Exactly as for 'request_negotiate'
+
+ - Executes the next negotiation step with the peer. The
+ 'objective' parameter contains the next value being proffered
+ by the ASA in this step. It must also contain the latest
+ 'loop_count' value received from request_negotiate() or
+ negotiate_step().
+
+ - Asynchronous Mechanisms:
+
+ Threaded implementation: Usually called in the same thread as
+ the preceding 'request_negotiate' or 'listen_negotiate',
+ with the same value of 'session_handle'.
+
+ Event loop implementation: Must use the same value of
+ 'session_handle' returned by the preceding
+ 'request_negotiate' or 'listen_negotiate'.
+
+ * negotiate_wait()
+
+ This function is used by either ASA in a negotiation session to
+ delay the next step in negotiation.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ session_handle (structure)
+
+ timeout (unsigned integer)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - Requests the remote peer to delay the negotiation session by
+ 'timeout' milliseconds, thereby extending the original timeout.
+ This function simply triggers a GRASP Confirm Waiting message
+ (see [RFC8990] for details).
+
+ - Asynchronous Mechanisms:
+
+ Threaded implementation: Called in the same thread as the
+ preceding 'request_negotiate' or 'listen_negotiate', with
+ the same value of 'session_handle'.
+
+ Event loop implementation: Must use the same value of
+ 'session_handle' returned by the preceding
+ 'request_negotiate' or 'listen_negotiate'.
+
+ * end_negotiate()
+
+ This function is used by either ASA in a negotiation session to
+ end a negotiation.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ session_handle (structure)
+
+ result (Boolean)
+
+ reason (UTF-8 string)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - End the negotiation session:
+
+ 'result' = True for accept (successful negotiation), and False
+ for decline (failed negotiation).
+
+ 'reason' = string describing reason for decline (may be null;
+ ignored if accept).
+
+ - Asynchronous Mechanisms:
+
+ Threaded implementation: Called in the same thread as the
+ preceding 'request_negotiate' or 'listen_negotiate', with
+ the same value of 'session_handle'.
+
+ Event loop implementation: Must use the same value of
+ 'session_handle' returned by the preceding
+ 'request_negotiate' or 'listen_negotiate'.
+
+2.3.6. Synchronization and Flooding
+
+ * synchronize()
+
+ This function is used by any ASA to cause synchronization of a
+ GRASP objective as a requester (client).
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ objective (structure)
+
+ peer (asa_locator)
+
+ timeout (unsigned integer)
+
+ - Return values:
+
+ errorcode (unsigned integer)
+
+ result (structure) (undefined unless successful)
+
+ - This call requests the synchronized value of the given
+ 'objective'.
+
+ - If the 'peer' parameter is null, and the objective is already
+ available in the local cache, the flooded objective is returned
+ immediately in the 'result' parameter. In this case, the
+ 'timeout' is ignored.
+
+ - If the 'peer' parameter is not null, or a cached value is not
+ available, synchronization with a discovered ASA is performed.
+ If successful, the retrieved objective is returned in the
+ 'result' value.
+
+ - The 'peer' parameter is an 'asa_locator' as returned by
+ discover(). If 'peer' is null, GRASP discovery is
+ automatically performed first to find a suitable peer (i.e.,
+ any node that supports the objective in question).
+
+ - The 'timeout' parameter is described in Section 2.3.2.3.
+
+ - This call should be repeated whenever the latest value is
+ needed.
+
+ - Asynchronous Mechanisms:
+
+ Threaded implementation: Call in a separate thread if
+ asynchronous operation is required.
+
+ Event loop implementation: An additional in/out
+ 'session_handle' parameter is used, as in
+ request_negotiate(). If the 'errorcode' parameter has the
+ value 2 ('noReply'), no response has been received so far.
+ The 'session_handle' parameter must be presented in
+ subsequent calls.
+
+ - In the case of failure, an exponential backoff is recommended
+ before retrying (Section 3).
+
+ * listen_synchronize()
+
+ This function is used by an ASA to start acting as a
+ synchronization responder (listener) for a given GRASP objective.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ objective (structure)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - This instructs GRASP to listen for synchronization requests for
+ the given objective and to respond with the value given in the
+ 'objective' parameter. It also enables discovery responses for
+ the objective, as mentioned under register_objective() in
+ Section 2.3.3.
+
+ - This call is non-blocking and may be repeated whenever the
+ value changes.
+
+ * stop_listen_synchronize()
+
+ This function is used by an ASA to stop acting as a
+ synchronization responder (listener) for a given GRASP objective.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ objective (structure)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - This call instructs GRASP to stop listening for synchronization
+ requests for the given 'objective', i.e., it cancels a previous
+ listen_synchronize.
+
+ * flood()
+
+ This function is used by an ASA to flood one or more GRASP
+ objectives throughout the Autonomic Network.
+
+ Note that each GRASP node caches all flooded objectives that it
+ receives, until each one's time to live expires. Cached
+ objectives are tagged with their origin as well as an expiry time,
+ so multiple copies of the same objective may be cached
+ simultaneously. Further details are given in "Flood
+ Synchronization Message" (Section 2.8.11 of [RFC8990]).
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ ttl (unsigned integer)
+
+ tagged_objective_list (structure)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - This call instructs GRASP to flood the given synchronization
+ objective(s) and their value(s) and associated locator(s) to
+ all GRASP nodes.
+
+ - The 'ttl' parameter is the valid lifetime (time to live) of the
+ flooded data in milliseconds (0 = infinity).
+
+ - The 'tagged_objective_list' parameter is a list of one or more
+ 'tagged_objective' couplets. The 'locator' parameter that tags
+ each objective is normally null but may be a valid
+ 'asa_locator'. Infrastructure ASAs needing to flood an
+ {address, protocol, port} 3-tuple with an objective create an
+ asa_locator object to do so. If the IP address in that locator
+ is the unspecified address ('::'), it is replaced by the link-
+ local address of the sending node in each copy of the flood
+ multicast, which will be forced to have a loop count of 1.
+ This feature is for objectives that must be restricted to the
+ local link.
+
+ - The function checks that the ASA registered each objective.
+
+ - This call may be repeated whenever any value changes.
+
+ * get_flood()
+
+ This function is used by any ASA to obtain the current value of a
+ flooded GRASP objective.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ objective (structure)
+
+ - Return values:
+
+ errorcode (unsigned integer)
+
+ tagged_objective_list (structure) (undefined unless
+ successful)
+
+ - This call instructs GRASP to return the given synchronization
+ objective if it has been flooded and its lifetime has not
+ expired.
+
+ - The 'tagged_objective_list' parameter is a list of
+ 'tagged_objective' couplets, each one being a copy of the
+ flooded objective and a corresponding locator. Thus, if the
+ same objective has been flooded by multiple ASAs, the recipient
+ can distinguish the copies.
+
+ - Note that this call is for advanced ASAs. In a simple case, an
+ ASA can simply call synchronize() in order to get a valid
+ flooded objective.
+
+ * expire_flood()
+
+ This function may be used by an ASA to expire specific entries in
+ the local GRASP flood cache.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ tagged_objective (structure)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - This is a call that can only be used after a preceding call to
+ get_flood() by an ASA that is capable of deciding that the
+ flooded value is stale or invalid. Use with care.
+
+ - The 'tagged_objective' parameter is the one to be expired.
+
+2.3.7. Invalid Message Function
+
+ * send_invalid()
+
+ This function may be used by any ASA to stop an ongoing GRASP
+ session.
+
+ - Input parameters:
+
+ asa_handle (unsigned integer)
+
+ session_handle (structure)
+
+ info (bytes)
+
+ - Return value:
+
+ errorcode (unsigned integer)
+
+ - Sends a GRASP Invalid message (M_INVALID), as described in
+ [RFC8990]. It should not be used if end_negotiate() would be
+ sufficient. Note that this message may be used in response to
+ any unicast GRASP message that the receiver cannot interpret
+ correctly. In most cases, this message will be generated
+ internally by a GRASP implementation.
+
+ 'info' = optional diagnostic data supplied by the ASA. It may
+ be raw bytes from the invalid message.
+
+3. Security Considerations
+
+ Security considerations for the GRASP protocol are discussed in
+ [RFC8990]. These include denial-of-service issues, even though these
+ are considered a low risk in the ACP. In various places, GRASP
+ recommends an exponential backoff. An ASA using the API should use
+ exponential backoff after failed discover(), req_negotiate(), or
+ synchronize() operations. The timescale for such backoffs depends on
+ the semantics of the GRASP objective concerned. Additionally, a
+ flood() operation should not be repeated at shorter intervals than is
+ useful. The appropriate interval depends on the semantics of the
+ GRASP objective concerned. These precautions are intended to assist
+ the detection of denial-of-service attacks.
+
+ As a general precaution, all ASAs able to handle multiple negotiation
+ or synchronization requests in parallel may protect themselves
+ against a denial-of-service attack by limiting the number of requests
+ they handle simultaneously and silently discarding excess requests.
+ It might also be useful for the GRASP core to limit the number of
+ objectives registered by a given ASA, the total number of ASAs
+ registered, and the total number of simultaneous sessions, to protect
+ system resources. During times of high autonomic activity, such as
+ recovery from widespread faults, ASAs may experience many GRASP
+ session failures. Guidance on making ASAs suitably robust is given
+ in [ASA-GUIDE].
+
+ As noted earlier, the trust model is that all ASAs in a given
+ Autonomic Network communicate via a secure autonomic control plane;
+ therefore, they trust each other's messages. Specific authorization
+ of ASAs to use particular GRASP objectives is a subject for future
+ study, also briefly discussed in [RFC8990].
+
+ The careful reader will observe that a malicious ASA could extend a
+ negotiation session indefinitely by use of the negotiate_wait()
+ function or by manipulating the loop count of an objective. A
+ robustly implemented ASA could detect such behavior by a peer and
+ break off negotiation.
+
+ The 'asa_handle' is used in the API as a first line of defense
+ against a malware process attempting to imitate a legitimately
+ registered ASA. The 'session_handle' is used in the API as a first
+ line of defense against a malware process attempting to hijack a
+ GRASP session. Both these handles are likely to be created using
+ GRASP's 32-bit pseudorandom Session ID. By construction, GRASP
+ avoids the risk of Session ID collisions (see "Session Identifier
+ (Session ID)", Section 2.7 of [RFC8990]). There remains a finite
+ probability that an attacker could guess a Session ID,
+ session_handle, or asa_handle. However, this would only be of value
+ to an attacker that had already penetrated the ACP, which would allow
+ many other simpler forms of attack than hijacking GRASP sessions.
+
+4. IANA Considerations
+
+ This document has no IANA actions.
+
+5. References
+
+5.1. Normative References
+
+ [RFC8610] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data
+ Definition Language (CDDL): A Notational Convention to
+ Express Concise Binary Object Representation (CBOR) and
+ JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610,
+ June 2019, <https://www.rfc-editor.org/info/rfc8610>.
+
+ [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object
+ Representation (CBOR)", STD 94, RFC 8949,
+ DOI 10.17487/RFC8949, December 2020,
+ <https://www.rfc-editor.org/info/rfc8949>.
+
+ [RFC8990] Bormann, C., Carpenter, B., Ed., and B. Liu, Ed., "GeneRic
+ Autonomic Signaling Protocol (GRASP)", RFC 8990,
+ DOI 10.17487/RFC8990, May 2021,
+ <https://www.rfc-editor.org/info/rfc8990>.
+
+5.2. Informative References
+
+ [ANIMA-COORD]
+ Ciavaglia, L. and P. Peloso, "Autonomic Functions
+ Coordination", Work in Progress, Internet-Draft, draft-
+ ciavaglia-anima-coordination-01, 21 March 2016,
+ <https://tools.ietf.org/html/draft-ciavaglia-anima-
+ coordination-01>.
+
+ [ASA-GUIDE]
+ Carpenter, B., Ciavaglia, L., Jiang, S., and P. Peloso,
+ "Guidelines for Autonomic Service Agents", Work in
+ Progress, Internet-Draft, draft-ietf-anima-asa-guidelines-
+ 00, 14 November 2020, <https://tools.ietf.org/html/draft-
+ ietf-anima-asa-guidelines-00>.
+
+ [GRASP-DISTRIB]
+ Liu, B., Xiao, X., Hecker, A., Jiang, S., Despotovic, Z.,
+ and B. Carpenter, "Information Distribution over GRASP",
+ Work in Progress, Internet-Draft, draft-ietf-anima-grasp-
+ distribution-02, 8 March 2021,
+ <https://tools.ietf.org/html/draft-ietf-anima-grasp-
+ distribution-02>.
+
+ [libcbor] Kalvoda, P., "libcbor - libcbor 0.8.0 documentation",
+ April 2021, <https://libcbor.readthedocs.io/>.
+
+ [RFC8993] Behringer, M., Ed., Carpenter, B., Eckert, T., Ciavaglia,
+ L., and J. Nobre, "A Reference Model for Autonomic
+ Networking", RFC 8993, DOI 10.17487/RFC8993, May 2021,
+ <https://www.rfc-editor.org/info/rfc8993>.
+
+ [RFC8994] Eckert, T., Ed., Behringer, M., Ed., and S. Bjarnason, "An
+ Autonomic Control Plane (ACP)", RFC 8994,
+ DOI 10.17487/RFC8994, May 2021,
+ <https://www.rfc-editor.org/info/rfc8994>.
+
+ [RFC8995] Pritikin, M., Richardson, M., Eckert, T., Behringer, M.,
+ and K. Watsen, "Bootstrapping Remote Secure Key
+ Infrastructure (BRSKI)", RFC 8995, DOI 10.17487/RFC8995,
+ May 2021, <https://www.rfc-editor.org/info/rfc8995>.
+
+Appendix A. Error Codes
+
+ This appendix lists the error codes defined so far on the basis of
+ implementation experience, with suggested symbolic names and
+ corresponding descriptive strings in English. It is expected that
+ complete API implementations will provide for localization of these
+ descriptive strings, and that additional error codes will be needed
+ according to implementation details.
+
+ The error codes that may only be returned by one or two functions are
+ annotated accordingly, and the others may be returned by numerous
+ functions. The 'noSecurity' error will be returned to most calls if
+ GRASP is running in an insecure mode (i.e., with no secure substrate
+ such as the ACP), except for the specific DULL usage mode described
+ in "Discovery Unsolicited Link-Local (DULL) GRASP" (Section 2.5.2 of
+ [RFC8990].
+
+ +================+=======+=================================+
+ | Name | Error | Description |
+ | | Code | |
+ +================+=======+=================================+
+ | ok | 0 | "OK" |
+ +----------------+-------+---------------------------------+
+ | declined | 1 | "Declined" (req_negotiate, |
+ | | | negotiate_step) |
+ +----------------+-------+---------------------------------+
+ | noReply | 2 | "No reply" (indicates waiting |
+ | | | state in event loop calls) |
+ +----------------+-------+---------------------------------+
+ | unspec | 3 | "Unspecified error" |
+ +----------------+-------+---------------------------------+
+ | ASAfull | 4 | "ASA registry full" |
+ | | | (register_asa) |
+ +----------------+-------+---------------------------------+
+ | dupASA | 5 | "Duplicate ASA name" |
+ | | | (register_asa) |
+ +----------------+-------+---------------------------------+
+ | noASA | 6 | "ASA not registered" |
+ +----------------+-------+---------------------------------+
+ | notYourASA | 7 | "ASA registered but not by you" |
+ | | | (deregister_asa) |
+ +----------------+-------+---------------------------------+
+ | notBoth | 8 | "Objective cannot support both |
+ | | | negotiation and |
+ | | | synchronization" (register_obj) |
+ +----------------+-------+---------------------------------+
+ | notDry | 9 | "Dry-run allowed only with |
+ | | | negotiation" (register_obj) |
+ +----------------+-------+---------------------------------+
+ | notOverlap | 10 | "Overlap not supported by this |
+ | | | implementation" (register_obj) |
+ +----------------+-------+---------------------------------+
+ | objFull | 11 | "Objective registry full" |
+ | | | (register_obj) |
+ +----------------+-------+---------------------------------+
+ | objReg | 12 | "Objective already registered" |
+ | | | (register_obj) |
+ +----------------+-------+---------------------------------+
+ | notYourObj | 13 | "Objective not registered by |
+ | | | this ASA" |
+ +----------------+-------+---------------------------------+
+ | notObj | 14 | "Objective not found" |
+ +----------------+-------+---------------------------------+
+ | notNeg | 15 | "Objective not negotiable" |
+ | | | (req_negotiate, |
+ | | | listen_negotiate) |
+ +----------------+-------+---------------------------------+
+ | noSecurity | 16 | "No security" |
+ +----------------+-------+---------------------------------+
+ | noDiscReply | 17 | "No reply to discovery" |
+ | | | (req_negotiate) |
+ +----------------+-------+---------------------------------+
+ | sockErrNegRq | 18 | "Socket error sending |
+ | | | negotiation request" |
+ | | | (req_negotiate) |
+ +----------------+-------+---------------------------------+
+ | noSession | 19 | "No session" |
+ +----------------+-------+---------------------------------+
+ | noSocket | 20 | "No socket" |
+ +----------------+-------+---------------------------------+
+ | loopExhausted | 21 | "Loop count exhausted" |
+ | | | (negotiate_step) |
+ +----------------+-------+---------------------------------+
+ | sockErrNegStep | 22 | "Socket error sending |
+ | | | negotiation step" |
+ | | | (negotiate_step) |
+ +----------------+-------+---------------------------------+
+ | noPeer | 23 | "No negotiation peer" |
+ | | | (req_negotiate, negotiate_step) |
+ +----------------+-------+---------------------------------+
+ | CBORfail | 24 | "CBOR decode failure" |
+ | | | (req_negotiate, negotiate_step, |
+ | | | synchronize) |
+ +----------------+-------+---------------------------------+
+ | invalidNeg | 25 | "Invalid Negotiate message" |
+ | | | (req_negotiate, negotiate_step) |
+ +----------------+-------+---------------------------------+
+ | invalidEnd | 26 | "Invalid end message" |
+ | | | (req_negotiate, negotiate_step) |
+ +----------------+-------+---------------------------------+
+ | noNegReply | 27 | "No reply to negotiation step" |
+ | | | (req_negotiate, negotiate_step) |
+ +----------------+-------+---------------------------------+
+ | noValidStep | 28 | "No valid reply to negotiation |
+ | | | step" (req_negotiate, |
+ | | | negotiate_step) |
+ +----------------+-------+---------------------------------+
+ | sockErrWait | 29 | "Socket error sending wait |
+ | | | message" (negotiate_wait) |
+ +----------------+-------+---------------------------------+
+ | sockErrEnd | 30 | "Socket error sending end |
+ | | | message" (end_negotiate, |
+ | | | send_invalid) |
+ +----------------+-------+---------------------------------+
+ | IDclash | 31 | "Incoming request Session ID |
+ | | | clash" (listen_negotiate) |
+ +----------------+-------+---------------------------------+
+ | notSynch | 32 | "Not a synchronization |
+ | | | objective" (synchronize, |
+ | | | get_flood) |
+ +----------------+-------+---------------------------------+
+ | notFloodDisc | 33 | "Not flooded and no reply to |
+ | | | discovery" (synchronize) |
+ +----------------+-------+---------------------------------+
+ | sockErrSynRq | 34 | "Socket error sending synch |
+ | | | request" (synchronize) |
+ +----------------+-------+---------------------------------+
+ | noListener | 35 | "No synch listener" |
+ | | | (synchronize) |
+ +----------------+-------+---------------------------------+
+ | noSynchReply | 36 | "No reply to synchronization |
+ | | | request" (synchronize) |
+ +----------------+-------+---------------------------------+
+ | noValidSynch | 37 | "No valid reply to |
+ | | | synchronization request" |
+ | | | (synchronize) |
+ +----------------+-------+---------------------------------+
+ | invalidLoc | 38 | "Invalid locator" (flood) |
+ +----------------+-------+---------------------------------+
+
+ Table 1: Error Codes
+
+Acknowledgements
+
+ Excellent suggestions were made by Ignas Bagdonas, Carsten Bormann,
+ Laurent Ciavaglia, Roman Danyliw, Toerless Eckert, Benjamin Kaduk,
+ Erik Kline, Murray Kucherawy, Paul Kyzivat, Guangpeng Li, Michael
+ Richardson, Joseph Salowey, Éric Vyncke, Magnus Westerlund, Rob
+ Wilton, and other participants in the ANIMA WG and the IESG.
+
+Authors' Addresses
+
+ Brian E. Carpenter
+ School of Computer Science
+ University of Auckland
+ PB 92019
+ Auckland 1142
+ New Zealand
+
+ Email: brian.e.carpenter@gmail.com
+
+
+ Bing Liu (editor)
+ Huawei Technologies
+ Q14, Huawei Campus
+ No.156 Beiqing Road
+ Hai-Dian District, Beijing
+ 100095
+ China
+
+ Email: leo.liubing@huawei.com
+
+
+ Wendong Wang
+ BUPT University
+ Beijing University of Posts & Telecom.
+ No.10 Xitucheng Road
+ Hai-Dian District, Beijing 100876
+ China
+
+ Email: wdwang@bupt.edu.cn
+
+
+ Xiangyang Gong
+ BUPT University
+ Beijing University of Posts & Telecom.
+ No.10 Xitucheng Road
+ Hai-Dian District, Beijing 100876
+ China
+
+ Email: xygong@bupt.edu.cn