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