idnits 2.17.1 draft-ietf-anima-grasp-api-06.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** There are 5 instances of too long lines in the document, the longest one being 8 characters in excess of 72. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (12 June 2020) is 1413 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- == Outdated reference: A later version (-30) exists of draft-ietf-anima-autonomic-control-plane-24 == Outdated reference: A later version (-45) exists of draft-ietf-anima-bootstrapping-keyinfra-41 Summary: 1 error (**), 0 flaws (~~), 3 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group B. E. Carpenter 3 Internet-Draft Univ. of Auckland 4 Intended status: Informational B. Liu, Ed. 5 Expires: 14 December 2020 Huawei Technologies 6 W. Wang 7 X. Gong 8 BUPT University 9 12 June 2020 11 Generic Autonomic Signaling Protocol Application Program Interface 12 (GRASP API) 13 draft-ietf-anima-grasp-api-06 15 Abstract 17 This document is a conceptual outline of an application programming 18 interface (API) for the Generic Autonomic Signaling Protocol (GRASP). 19 Such an API is needed for Autonomic Service Agents (ASA) calling the 20 GRASP protocol module to exchange autonomic network messages with 21 other ASAs. Since GRASP is designed to support asynchronous 22 operations, the API will need to be adapted to the support for 23 asynchronicity in various languages and operating systems. 25 Status of This Memo 27 This Internet-Draft is submitted in full conformance with the 28 provisions of BCP 78 and BCP 79. 30 Internet-Drafts are working documents of the Internet Engineering 31 Task Force (IETF). Note that other groups may also distribute 32 working documents as Internet-Drafts. The list of current Internet- 33 Drafts is at https://datatracker.ietf.org/drafts/current/. 35 Internet-Drafts are draft documents valid for a maximum of six months 36 and may be updated, replaced, or obsoleted by other documents at any 37 time. It is inappropriate to use Internet-Drafts as reference 38 material or to cite them other than as "work in progress." 40 This Internet-Draft will expire on 14 December 2020. 42 Copyright Notice 44 Copyright (c) 2020 IETF Trust and the persons identified as the 45 document authors. All rights reserved. 47 This document is subject to BCP 78 and the IETF Trust's Legal 48 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 49 license-info) in effect on the date of publication of this document. 50 Please review these documents carefully, as they describe your rights 51 and restrictions with respect to this document. Code Components 52 extracted from this document must include Simplified BSD License text 53 as described in Section 4.e of the Trust Legal Provisions and are 54 provided without warranty as described in the Simplified BSD License. 56 Table of Contents 58 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 59 2. GRASP API for ASA . . . . . . . . . . . . . . . . . . . . . . 4 60 2.1. Design Assumptions . . . . . . . . . . . . . . . . . . . 4 61 2.2. Asynchronous Operations . . . . . . . . . . . . . . . . . 5 62 2.2.1. Alternative Asynchronous Mechanisms . . . . . . . . . 6 63 2.2.2. Multiple Negotiation Scenario . . . . . . . . . . . . 7 64 2.2.3. Overlapping Sessions and Operations . . . . . . . . . 8 65 2.3. API definition . . . . . . . . . . . . . . . . . . . . . 8 66 2.3.1. Parameters and data structures . . . . . . . . . . . 8 67 2.3.2. Registration . . . . . . . . . . . . . . . . . . . . 12 68 2.3.3. Discovery . . . . . . . . . . . . . . . . . . . . . . 14 69 2.3.4. Negotiation . . . . . . . . . . . . . . . . . . . . . 15 70 2.3.5. Synchronization and Flooding . . . . . . . . . . . . 21 71 2.3.6. Invalid Message Function . . . . . . . . . . . . . . 24 72 3. Implementation Status [RFC Editor: please remove] . . . . . . 25 73 4. Security Considerations . . . . . . . . . . . . . . . . . . . 25 74 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 25 75 6. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 25 76 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 25 77 7.1. Normative References . . . . . . . . . . . . . . . . . . 25 78 7.2. Informative References . . . . . . . . . . . . . . . . . 26 79 Appendix A. Error Codes . . . . . . . . . . . . . . . . . . . . 26 80 Appendix B. Change log [RFC Editor: Please remove] . . . . . . . 27 81 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 29 83 1. Introduction 85 As defined in [I-D.ietf-anima-reference-model], the Autonomic Service 86 Agent (ASA) is the atomic entity of an autonomic function, and it is 87 instantiated on autonomic nodes. When ASAs communicate with each 88 other, they should use the Generic Autonomic Signaling Protocol 89 (GRASP) [I-D.ietf-anima-grasp]. 91 As the following figure shows, a GRASP implementation could contain 92 two major sub-layers. The bottom is the GRASP base protocol module, 93 which is only responsible for sending and receiving GRASP messages 94 and maintaining shared data structures. The upper layer contains 95 some extended functions based upon GRASP basic protocol. For 96 example, [I-D.liu-anima-grasp-distribution] describes a possible 97 extended function. 99 Multiple ASAs in a single node will share the same instance of GRASP, 100 much as multiple applications share a single TCP/IP stack. This 101 aspect is hidden from individual ASAs by the API, and is not further 102 discussed here. 104 It is desirable that ASAs can be designed as portable user-space 105 programs using a system-independent API. In many implementations, 106 the GRASP module will therefore be split into two layers. The top 107 layer is a library that provides the API and communicates directly 108 with ASAs. The lower layer is a daemon, or a set of sub-services, 109 providing GRASP core functions that are independent of specific ASAs, 110 such as multicast handling and relaying, and common data structures 111 such as the discovery cache. The GRASP API library would need to 112 communicate with the GRASP core via an inter-process communication 113 (IPC) mechanism. The details of this are system-dependent. 115 +--------------+ +--------------+ 116 | ASAs | | ASAs | 117 +--------------+ +--------------+ 118 | | | 119 | | GRASP Function | 120 | | API | 121 | +------------------+ |GRASP API 122 | | GRASP Extended | | 123 | | Function Modules | | 124 | +------------------+ | 125 | | | 126 +------------------------------------------+ 127 | GRASP API Library | 128 | GRASP Modules - - - - - - - - - - - - - | 129 | GRASP Core (Daemon) | 130 +------------------------------------------+ 132 Both the GRASP library and the extended function modules should be 133 available to the ASAs. However, since the extended functions are 134 expected to be added in an incremental manner, they will be the 135 subject of future documents. This document only describes the basic 136 GRASP API. 138 The functions provided by the API do not map one-to-one onto GRASP 139 messages. Rather, they are intended to offer convenient support for 140 message sequences (such as a discovery request followed by responses 141 from several peers, or a negotiation request followed by various 142 possible responses). This choice was made to assist ASA programmers 143 in writing code based on their application requirements rather than 144 needing to understand protocol details. 146 Note that a simple autonomic node might contain very few ASAs in 147 addition to the autonomic infrastructure components described in 148 [I-D.ietf-anima-bootstrapping-keyinfra] and 149 [I-D.ietf-anima-autonomic-control-plane]. Such a node might directly 150 integrate GRASP in its code and therefore not require this API to be 151 installed. However, the programmer would then need a deeper 152 understanding of the GRASP protocol than is needed to use the API. 154 This document gives a conceptual outline of the API. It is not a 155 formal specification for any particular programming language or 156 operating system, and it is expected that details will be clarified 157 in individual implementations. 159 2. GRASP API for ASA 161 2.1. Design Assumptions 163 The assumption of this document is that any Autonomic Service Agent 164 (ASA) needs to call a GRASP module. The latter handles protocol 165 details (security, sending and listening for GRASP messages, waiting, 166 caching discovery results, negotiation looping, sending and receiving 167 sychronization data, etc.) but understands nothing about individual 168 GRASP objectives (Section 2.10 of [I-D.ietf-anima-grasp]). The 169 semantics of objectives are unknown to the GRASP module and are 170 handled only by the ASAs. Thus, this is an abstract API for use by 171 ASAs. Individual language bindings should be defined in separate 172 documents. 174 Different ASAs may make different use of GRASP features: 176 * Use GRASP only for discovery purposes. 178 * Use GRASP negotiation but only as an initiator (client). 180 * Use GRASP negotiation but only as a responder. 182 * Use GRASP negotiation as an initiator or responder. 184 * Use GRASP synchronization but only as an initiator (recipient). 186 * Use GRASP synchronization but only as a responder and/or flooder. 188 * Use GRASP synchronization as an initiator, responder and/or 189 flooder. 191 The API also assumes that one ASA may support multiple objectives. 192 Nothing prevents an ASA from supporting some objectives for 193 synchronization and others for negotiation. 195 The API design assumes that the operating system and programming 196 language provide a mechanism for simultaneous asynchronous 197 operations. This is discussed in detail in Section 2.2. 199 A few items are out of scope in this version, since practical 200 experience is required before including them: 202 * Authorization of ASAs is not defined as part of GRASP and is not 203 supported. 205 * User-supplied explicit locators for an objective are not 206 supported. The GRASP core will supply the locator, using the ACP 207 address of the node concerned. 209 * The Rapid mode of GRASP (Section 2.5.4 of [I-D.ietf-anima-grasp]) 210 is not supported. 212 2.2. Asynchronous Operations 214 GRASP depends on asynchronous operations and wait states, and its 215 messages are not idempotent, meaning that repeating a message may 216 cause repeated changes of state in the recipient ASA. Many ASAs will 217 need to support several concurrent operations; for example an ASA 218 might need to negotiate one objective with a peer while discovering 219 and synchronizing a different objective with a different peer. 220 Alternatively, an ASA which acts as a resource manager might need to 221 run simultaneous negotiations for a given objective with multiple 222 different peers. Such an ASA will probably need to support 223 uninterruptible atomic changes to its internal data structures, using 224 a mechanism provided by the operating system and programming language 225 in use. 227 2.2.1. Alternative Asynchronous Mechanisms 229 Thus, some ASAs need to support asynchronous operations, and 230 therefore the GRASP core must do so. Depending on both the operating 231 system and the programming language in use, there are three main 232 techniques for such parallel operations: multi-threading, an event 233 loop structure using polling, and an event loop structure using 234 callback functions. 236 1. In multi-threading, the operating system and language will 237 provide the necessary support for asynchronous operations, 238 including creation of new threads, context switching between 239 threads, queues, locks, and implicit wait states. In this case, 240 API calls can be treated as simple function calls within their 241 own thread, even if the function includes wait states, blocking 242 and queueing. Concurrent operations will each run in their own 243 threads. For example, the discover() call may not return until 244 discovery results have arrived or a timeout has occurred. If the 245 ASA has other work to do, the discover() call must be in a thread 246 of its own. 248 2. In an event loop implementation with polling, blocking calls are 249 not acceptable. Therefore all calls must be non-blocking, and 250 the main loop could support multiple GRASP sessions in parallel 251 by repeatedly polling each one for a change of state. To 252 facilitate this, the API implementation would provide non- 253 blocking versions of all the functions that otherwise involve 254 blocking and queueing. In these calls, a 'noReply' code will be 255 returned by each call instead of blocking, until such time as the 256 event for which it is waiting (or a failure) has occurred. Thus, 257 for example, discover() would return 'noReply' instead of waiting 258 until discovery has succeeded or timed out. The discover() call 259 would be repeated in every cycle of the main loop until it 260 completes. Effectively, it becomes a polling call. 262 3. In an event loop implementation with callbacks, the ASA 263 programmer would provide a callback function for each 264 asynchronous operation, e.g. discovery_received(). This would be 265 called asynchronously when a reply is received or a failure such 266 as a timeout occurs. 268 The following calls involve waiting for a remote operation, so they 269 could use a polling or callback mechanism. In a threaded mechanism, 270 they will usually require to be called in a separate thread: 272 discover() whose callback would be discovery_received(). 274 request_negotiate() whose callback would be 275 negotiate_step_received(). 277 negotiate_step() whose callback would be 278 negotiate_step_received(). 280 listen_negotiate() whose callback would be 281 negotiate_step_received(). 283 synchronize() whose callback would be synchronization_received(). 285 2.2.2. Multiple Negotiation Scenario 287 The design of GRASP allows the following scenario. Consider an ASA 288 "A" that acts as a resource allocator for some objective. An ASA "B" 289 launches a negotiation with "A" to obtain or release a quantity of 290 the resource. While this negotatition is under way, "B" chooses to 291 launch a second simultaneous negotiation with "A" for a different 292 quantity of the same resource. "A" must therefore conduct two 293 separate negotiation sessions at the same time with the same peer, 294 and must not mix them up. 296 Note that ASAs could be designed to avoid such a scenario, i.e. 297 restricted to exactly one negotiation session at a time for a given 298 objective, but this would be a voluntary restriction not required by 299 the GRASP protocol. In fact it is an assumption of GRASP that an ASA 300 managing a resource may need to conduct multiple parallel 301 negotiations, possibly with the same peer. Therefore, the API design 302 allows for such scenarios. 304 In the callback model, for the scenario just described, the ASAs "A" 305 and "B" will each provide two instances of negotiate_step_received(), 306 one for each session. For this reason, each ASA must be able to 307 distinguish the two sessions, and the peer's IP address is not 308 sufficient for this. It is also not safe to rely on transport port 309 numbers for this, since future variants of GRASP might use shared 310 ports rather than a separate port per session. This is why the GRASP 311 design includes a session identifier. Thus, when necessary, a 312 'session_nonce' parameter is used in the API to distinguish 313 simultaneous GRASP sessions from each other, so that any number of 314 sessions may proceed asynchronously in parallel. 316 2.2.3. Overlapping Sessions and Operations 318 In calls where it is used, the 'session_nonce' is an opaque read/ 319 write parameter. On the first call, it is set to a null value, and 320 the API returns a non-null 'session_nonce' value based on the GRASP 321 session identifier. This value must be used in all subsequent calls 322 for the same session, and will be provided as a parameter in the 323 callback functions. By this mechanism, multiple overlapping sessions 324 can be distinguished, both in the ASA and in the GRASP core. The 325 value of the 'session_nonce" is opaque to the ASA. 327 An additional mechanism that might increase efficiency for polling 328 implementations is to add a general call, say notify(), which would 329 check the status of all outstanding operations for the calling ASA 330 and return the session_nonce values for all sessions that have 331 changed state. This would eliminate the need for repeated calls to 332 the individual functions returning a 'noReply'. This call is not 333 described below as the details are likely to be implementation- 334 specific. 336 An implication of the above for all GRASP implementations is that the 337 GRASP core must keep state for each GRASP operation in progress, most 338 likely keyed by the GRASP Session ID and the GRASP source address of 339 the session initiator. Even in a threaded implementation, the GRASP 340 core will need such state internally. The session_nonce parameter 341 exposes this aspect of the implementation. 343 2.3. API definition 345 2.3.1. Parameters and data structures 347 This section describes parameters and data structures used in 348 multiple API calls. 350 2.3.1.1. Errorcode 352 All functions in the API have an unsigned 'errorcode' integer as 353 their return value (the first returned value in languages that allow 354 multiple returned parameters). An errorcode of zero indicates 355 success. Any other value indicates failure of some kind. The first 356 three errorcodes have special importance: 358 1. Declined: used to indicate that the other end has sent a GRASP 359 Negotiation End message (M_END) with a Decline option 360 (O_DECLINE). 362 2. No reply: used in non-blocking calls to indicate that the other 363 end has sent no reply so far (see Section 2.2). 365 3. Unspecified error: used when no more specific error code applies. 367 Appendix A gives a full list of currently suggested error codes, 368 based on implementation experience. While there is no absolute 369 requirement for all implementations to use the same error codes, this 370 is highly recommended for portability of applications. 372 2.3.1.2. Timeout 374 Wherever a 'timeout' parameter appears, it is an integer expressed in 375 milliseconds. If it is zero, the GRASP default timeout 376 (GRASP_DEF_TIMEOUT, see [I-D.ietf-anima-grasp]) will apply. If no 377 response is received before the timeout expires, the call will fail 378 unless otherwise noted. 380 2.3.1.3. Objective 382 An 'objective' parameter is a data structure with the following 383 components: 385 * name (UTF-8 string) - the objective's name 387 * neg (Boolean flag) - True if objective supports negotiation 388 (default False) 390 * synch (Boolean flag) - True if objective supports synchronization 391 (default False) 393 * dry (Boolean flag) - True if objective supports dry-run 394 negotiation (default False) 396 - Note 1: Only one of 'synch' or 'neg' may be True. 398 - Note 2: 'dry' must not be True unless 'neg' is also True. 400 - Note 3: In a language such as C the preferred implementation 401 may be to represent the Boolean flags as bits in a single byte. 403 * loop_count (integer) - Limit on negotiation steps etc. (default 404 GRASP_DEF_LOOPCT, see [I-D.ietf-anima-grasp]) 406 * value - a specific data structure expressing the value of the 407 objective. The format is language dependent, with the constraint 408 that it can be validly represented in CBOR (default integer = 0). 410 An essential requirement for all language mappings and all 411 implementations is that, regardless of what other options exist 412 for a language-specific represenation of the value, there is 413 always an option to use a CBOR byte string as the value. The API 414 will then wrap this byte string in CBOR Tag 24 for transmission 415 via GRASP, and unwrap it after reception. 417 An example data structure definition for an objective in the C 418 language, assuming the use of a particular CBOR library, is: 420 typedef struct { 421 char *name; 422 uint8_t flags; // flag bits as defined by GRASP 423 int loop_count; 424 int value_size; // size of value in bytes 425 cbor_mutable_data cbor_value; 426 // CBOR bytestring (libcbor/cbor/data.h) 427 } objective; 429 An example data structure definition for an objective in the 430 Python language is: 432 class objective: 433 """A GRASP objective""" 434 def __init__(self, name): 435 self.name = name # Unique name (string) 436 self.negotiate = False # True if objective supports negotiation 437 self.dryrun = False # True if objective supports dry-run neg. 438 self.synch = False # True if objective supports synch 439 self.loop_count = GRASP_DEF_LOOPCT # Default starting value 440 self.value = 0 # Place holder; any valid Python object 442 2.3.1.4. ASA_locator 444 An 'ASA_locator' parameter is a data structure with the following 445 contents: 447 * locator - The actual locator, either an IP address or an ASCII 448 string. 450 * ifi (integer) - The interface identifier index via which this was 451 discovered - probably no use to a normal ASA 453 * expire (system dependent type) - The time on the local system 454 clock when this locator will expire from the cache 456 * The following cover all locator types currently supported by 457 GRASP: 459 - is_ipaddress (Boolean) - True if the locator is an IP address 460 - is_fqdn (Boolean) - True if the locator is an FQDN 462 - is_uri (Boolean) - True if the locator is a URI 464 * diverted (Boolean) - True if the locator was discovered via a 465 Divert option 467 * protocol (integer) - Applicable transport protocol (IPPROTO_TCP or 468 IPPROTO_UDP) 470 * port (integer) - Applicable port number 472 2.3.1.5. Tagged_objective 474 A 'tagged_objective' parameter is a data structure with the following 475 contents: 477 * objective - An objective 479 * locator - The ASA_locator associated with the objective, or a null 480 value. 482 2.3.1.6. Asa_nonce 484 Although an authentication and authorization scheme for ASAs has not 485 been defined, the API provides a very simple hook for such a scheme. 486 When an ASA starts up, it registers itself with the GRASP core, which 487 provides it with an opaque nonce that, although not cryptographically 488 protected, would be difficult for a third party to predict. The ASA 489 must present this nonce in future calls. This mechanism will prevent 490 some elementary errors or trivial attacks such as an ASA manipulating 491 an objective it has not registered to use. 493 Thus, in most calls, an 'asa_nonce' parameter is required. It is 494 generated when an ASA first registers with GRASP, and the ASA must 495 then store the asa_nonce and use it in every subsequent GRASP call. 496 Any call in which an invalid nonce is presented will fail. It is an 497 up to 32-bit opaque value (for example represented as a uint32_t, 498 depending on the language). It should be unpredictable; a possible 499 implementation is to use the same mechanism that GRASP uses to 500 generate Session IDs [I-D.ietf-anima-grasp]. Another possible 501 implementation is to hash the name of the ASA with a locally defined 502 secret key. 504 2.3.1.7. Session_nonce 506 In some calls, a 'session_nonce' parameter is required. This is an 507 opaque data structure as far as the ASA is concerned, used to 508 identify calls to the API as belonging to a specific GRASP session 509 (see Section 2.2). In fully threaded implementations this parameter 510 might not be needed, but it is included to act as a session handle if 511 necessary. It will also allow GRASP to detect and ignore malicious 512 calls or calls from timed-out sessions. A possible implementation is 513 to form the nonce from the underlying GRASP Session ID and the source 514 address of the session. 516 2.3.2. Registration 518 These functions are used to register an ASA and the objectives that 519 it supports with the GRASP module. If an authorization model is 520 added to GRASP, these API calls would need to be modified 521 accordingly. 523 * register_asa() 525 - Input parameter: 527 name of the ASA (UTF-8 string) 529 - Return parameters: 531 errorcode (integer) 533 asa_nonce (integer) (if successful) 535 - This initialises state in the GRASP module for the calling 536 entity (the ASA). In the case of success, an 'asa_nonce' is 537 returned which the ASA must present in all subsequent calls. 538 In the case of failure, the ASA has not been authorized and 539 cannot operate. 541 * deregister_asa() 543 - Input parameters: 545 asa_nonce (integer) 547 name of the ASA (UTF-8 string) 549 - Return parameter: 551 errorcode (integer) 553 - This removes all state in the GRASP module for the calling 554 entity (the ASA), and deregisters any objectives it has 555 registered. Note that these actions must also happen 556 automatically if an ASA crashes. 558 - Note - the ASA name is strictly speaking redundant in this 559 call, but is present for clarity. 561 * register_objective() 563 - Input parameters: 565 asa_nonce (integer) 567 objective (structure) 569 ttl (integer - default GRASP_DEF_TIMEOUT) 571 discoverable (Boolean - default False) 573 overlap (Boolean - default False) 575 local (Boolean - default False) 577 - Return parameter: 579 errorcode (integer) 581 - This registers an objective that this ASA supports and may 582 modify. The 'objective' becomes a candidate for discovery. 583 However, discovery responses should not be enabled until the 584 ASA calls listen_negotiate() or listen_synchronize(), showing 585 that it is able to act as a responder. The ASA may negotiate 586 the objective or send synchronization or flood data. 587 Registration is not needed for "read-only" operations, i.e., 588 the ASA only wants to receive synchronization or flooded data 589 for the objective concerned. 591 - The 'ttl' parameter is the valid lifetime (time to live) in 592 milliseconds of any discovery response for this objective. The 593 default value should be the GRASP default timeout 594 (GRASP_DEF_TIMEOUT, see [I-D.ietf-anima-grasp]). 596 - If the parameter 'discoverable' is True, the objective is 597 immediately discoverable. This is intended for objectives that 598 are only defined for GRASP discovery, and which do not support 599 negotiation or synchronization. 601 - If the parameter 'overlap' is True, more than one ASA may 602 register this objective in the same GRASP instance. 604 - If the parameter 'local' is True, discovery must return a link- 605 local address. This feature is for objectives that must be 606 restricted to the local link. 608 - This call may be repeated for multiple objectives. 610 * deregister_objective() 612 - Input parameters: 614 asa_nonce (integer) 616 objective (structure) 618 - Return parameter: 620 errorcode (integer) 622 - The 'objective' must have been registered by the calling ASA; 623 if not, this call fails. Otherwise, it removes all state in 624 the GRASP module for the given objective. 626 2.3.3. Discovery 628 * discover() 630 - Input parameters: 632 asa_nonce (integer) 634 objective (structure) 636 timeout (integer) 638 age_limit (integer) 640 - Return parameters: 642 errorcode (integer) 644 locator_list (structure) 646 - This returns a list of discovered 'ASA_locator's for the given 647 objective. Note that this structure includes all the fields 648 described in Section 2.3.1.4. 650 - If the parameter 'age_limit' is greater than zero, any locally 651 cached locators for the objective whose remaining lifetime in 652 milliseconds is less than or equal to 'age_limit' are deleted 653 first. Thus 'age_limit' = 0 will flush all entries. 655 - If the parameter 'timeout' is zero, any remaining locally 656 cached locators for the objective are returned immediately and 657 no other action is taken. (Thus, a call with 'age_limit' and 658 'timeout' both equal to zero is pointless.) 660 - If the parameter 'timeout' is greater than zero, GRASP 661 discovery is performed, and all results obtained before the 662 timeout in milliseconds expires are returned. If no results 663 are obtained, an empty list is returned after the timeout. 664 That is not an error condition. 666 - Asynchronous Mechanisms: 668 o Threaded implementation: This should be called in a separate 669 thread if asynchronous operation is required. 671 o Event loop implementation: An additional read/write 672 'session_nonce' parameter is used. A callback may be used 673 in the case of a non-zero tiemout. 675 2.3.4. Negotiation 677 * request_negotiate() 679 - Input parameters: 681 asa_nonce (integer) 683 objective (structure) 685 peer (ASA_locator) 687 timeout (integer) 689 - Return parameters: 691 errorcode (integer) 693 session_nonce (structure) (if successful) 695 proffered_objective (structure) (if successful) 697 reason (string) (if negotiation declined) 699 - This function opens a negotiation session between two ASAs. 700 Note that GRASP currently does not support multi-party 701 negotiation, which would need to be added as an extended 702 function. 704 - The 'objective' parameter must include the requested value, and 705 its loop count should be set to a suitable value by the ASA. 706 If not, the GRASP default will apply. 708 - Note that a given negotiation session may or may not be a dry- 709 run negotiation; the two modes must not be mixed in a single 710 session. 712 - The 'peer' parameter is the target node; it must be an 713 'ASA_locator' as returned by discover(). If the peer is null, 714 GRASP discovery is performed first. 716 - If the 'errorcode' return parameter is 0, the negotiation has 717 successfully started. There are then two cases: 719 1. The 'session_nonce' parameter is null. In this case the 720 negotiation has succeeded (the peer has accepted the 721 request). The returned 'proffered_objective' contains the 722 value accepted by the peer. 724 2. The 'session_nonce' parameter is not null. In this case 725 negotiation must continue. The returned 726 'proffered_objective' contains the first value proffered by 727 the negotiation peer. Note that this instance of the 728 objective must be used in the subsequent negotiation call 729 because it also contains the current loop count. The 730 'session_nonce' must be presented in all subsequent 731 negotiation steps. 733 This function must be followed by calls to 'negotiate_step' 734 and/or 'negotiate_wait' and/or 'end_negotiate' until the 735 negotiation ends. 'request_negotiate' may then be called 736 again to start a new negotation. 738 - If the 'errorcode' parameter has the value 1 ('declined'), the 739 negotiation has been declined by the peer (M_END and O_DECLINE 740 features of GRASP). The 'reason' string is then available for 741 information and diagnostic use, but it may be a null string. 742 For this and any other error code, an exponential backoff is 743 recommended before any retry. 745 - Asynchronous Mechanisms: 747 o Threaded implementation: This should be called in a separate 748 thread if asynchronous operation is required. 750 o Event loop implementation: The 'session_nonce' parameter is 751 used in read/write mode. 753 - Use of dry run mode: This must be consistent within a GRASP 754 session. The state of the 'dry' flag in the initial 755 request_negotiate() call must be the same in all subsequent 756 negotiation steps of the same session. The semantics of the 757 dry run mode are built into the ASA; GRASP merely carries the 758 flag bit. 760 - Special note for the ACP infrastructure ASA: It is likely that 761 this ASA will need to discover and negotiate with its peers in 762 each of its on-link neighbors. It will therefore need to know 763 not only the link-local IP address but also the physical 764 interface and transport port for connecting to each neighbor. 765 One implementation approach to this is to include these details 766 in the 'session_nonce' data structure, which is opaque to 767 normal ASAs. 769 * listen_negotiate() 771 - Input parameters: 773 asa_nonce (integer) 775 objective (structure) 777 - Return parameters: 779 errorcode (integer) 781 session_nonce (structure) (if successful) 783 requested_objective (structure) (if successful) 785 - This function instructs GRASP to listen for negotiation 786 requests for the given 'objective'. It also enables discovery 787 responses for the objective, as mentioned under 788 register_objective() in Section 2.3.2. 790 - Asynchronous Mechanisms: 792 o Threaded implementation: It will block waiting for an 793 incoming request, so should be called in a separate thread 794 if asynchronous operation is required. If the ASA supports 795 multiple simultaneous transactions, a new thread must be 796 spawned for each new session. 798 o Event loop implementation: A read/write 'session_nonce' 799 parameter is used. If the ASA supports multiple 800 simultaneous transactions, a new event must be inserted in 801 the event loop for each new session. 803 - Unless there is an unexpected failure, this call only returns 804 after an incoming negotiation request. When it does so, 805 'requested_objective' contains the first value requested by the 806 negotiation peer. Note that this instance of the objective 807 must be used in the subsequent negotiation call because it also 808 contains the current loop count. The 'session_nonce' must be 809 presented in all subsequent negotiation steps. 811 - This function must be followed by calls to 'negotiate_step' 812 and/or 'negotiate_wait' and/or 'end_negotiate' until the 813 negotiation ends. 'listen_negotiate' may then be called again 814 to await a new negotation. 816 - If an ASA is capable of handling multiple negotiations 817 simultaneously, it may call 'listen_negotiate' simultaneously 818 from multiple threads. The API and GRASP implementation must 819 support re-entrant use of the listening state and the 820 negotiation calls. Simultaneous sessions will be distinguished 821 by the threads themselves, the GRASP Session IDs, and the 822 underlying unicast transport sockets. 824 * stop_listen_negotiate() 826 - Input parameters: 828 asa_nonce (integer) 830 objective (structure) 832 - Return parameter: 834 errorcode (integer) 836 - Instructs GRASP to stop listening for negotiation requests for 837 the given objective, i.e., cancels 'listen_negotiate'. 839 - Asynchronous Mechanisms: 841 o Threaded implementation: Must be called from a different 842 thread than 'listen_negotiate'. 844 o Event loop implementation: no special considerations. 846 * negotiate_step() 848 - Input parameters: 850 asa_nonce (integer) 852 session_nonce (structure) 854 objective (structure) 856 timeout (integer) 858 - Return parameters: 860 Exactly as for 'request_negotiate' 862 - Executes the next negotation step with the peer. The 863 'objective' parameter contains the next value being proffered 864 by the ASA in this step. 866 - Asynchronous Mechanisms: 868 o Threaded implementation: Called in the same thread as the 869 preceding 'request_negotiate' or 'listen_negotiate', with 870 the same value of 'session_nonce'. 872 o Event loop implementation: Must use the same value of 873 'session_nonce' returned by the preceding 874 'request_negotiate' or 'listen_negotiate'. 876 * negotiate_wait() 878 - Input parameters: 880 asa_nonce (integer) 882 session_nonce (structure) 884 timeout (integer) 886 - Return parameters: 888 errorcode (integer) 890 - Delay negotiation session by 'timeout' milliseconds, thereby 891 extending the original timeout. This function simply triggers 892 a GRASP Confirm Waiting message. 894 - Asynchronous Mechanisms: 896 o Threaded implementation: Called in the same thread as the 897 preceding 'request_negotiate' or 'listen_negotiate', with 898 the same value of 'session_nonce'. 900 o Event loop implementation: Must use the same value of 901 'session_nonce' returned by the preceding 902 'request_negotiate' or 'listen_negotiate'. 904 * end_negotiate() 906 - Input parameters: 908 asa_nonce (integer) 910 session_nonce (structure) 912 reply (Boolean) 914 reason (UTF-8 string) 916 - Return parameters: 918 errorcode (integer) 920 - End the negotiation session. 922 'reply' = True for accept (successful negotiation), False for 923 decline (failed negotiation). 925 'reason' = optional string describing reason for decline. 927 - Asynchronous Mechanisms: 929 o Threaded implementation: Called in the same thread as the 930 preceding 'request_negotiate' or 'listen_negotiate', with 931 the same value of 'session_nonce'. 933 o Event loop implementation: Must use the same value of 934 'session_nonce' returned by the preceding 935 'request_negotiate' or 'listen_negotiate'. 937 2.3.5. Synchronization and Flooding 939 * synchronize() 941 - Input parameters: 943 asa_nonce (integer) 945 objective (structure) 947 peer (ASA_locator) 949 timeout (integer) 951 - Return parameters: 953 errorcode (integer) 955 objective (structure) (if successful) 957 - This call requests the synchronized value of the given 958 'objective'. 960 - Since this is essentially a read operation, any ASA can do it, 961 unless an authorization model is added to GRASP in future. 962 Therefore the API checks that the ASA is registered, but the 963 objective does not need to be registered by the calling ASA. 965 - If the objective was already flooded, the flooded value is 966 returned immediately in the 'result' parameter. In this case, 967 the 'source' and 'timeout' are ignored. 969 - Otherwise, synchronization with a discovered ASA is performed. 970 The 'peer' parameter is an 'ASA_locator' as returned by 971 discover(). If 'peer' is null, GRASP discovery is performed 972 first. 974 - This call should be repeated whenever the latest value is 975 needed. 977 - Asynchronous Mechanisms: 979 o Threaded implementation: Call in a separate thread if 980 asynchronous operation is required. 982 o Event loop implementation: An additional read/write 983 'session_nonce' parameter is used. 985 - Since this is essentially a read operation, any ASA can use it. 986 Therefore GRASP checks that the calling ASA is registered but 987 the objective doesn't need to be registered by the calling ASA. 989 - In the case of failure, an exponential backoff is recommended 990 before retrying. 992 * listen_synchronize() 994 - Input parameters: 996 asa_nonce (integer) 998 objective (structure) 1000 - Return parameters: 1002 errorcode (integer) 1004 - This instructs GRASP to listen for synchronization requests for 1005 the given objective, and to respond with the value given in the 1006 'objective' parameter. It also enables discovery responses for 1007 the objective, as mentioned under register_objective() in 1008 Section 2.3.2. 1010 - This call is non-blocking and may be repeated whenever the 1011 value changes. 1013 * stop_listen_synchronize() 1015 - Input parameters: 1017 asa_nonce (integer) 1019 objective (structure) 1021 - Return parameters: 1023 errorcode (integer) 1025 - This call instructs GRASP to stop listening for synchronization 1026 requests for the given 'objective', i.e. it cancels a previous 1027 listen_synchronize. 1029 * flood() 1031 - Input parameters: 1033 asa_nonce (integer) 1035 ttl (integer) 1037 tagged_objective_list (structure) 1039 - Return parameters: 1041 errorcode (integer) 1043 - This call instructs GRASP to flood the given synchronization 1044 objective(s) and their value(s) and associated locator(s) to 1045 all GRASP nodes. 1047 - The 'ttl' parameter is the valid lifetime (time to live) of the 1048 flooded data in milliseconds (0 = infinity) 1050 - The 'tagged_objective_list' parameter is a list of one or more 1051 'tagged_objective' couplets. The 'locator' parameter that tags 1052 each objective is normally null but may be a valid 1053 'ASA_locator'. Infrastructure ASAs needing to flood an 1054 {address, protocol, port} 3-tuple with an objective create an 1055 ASA_locator object to do so. If the IP address in that locator 1056 is the unspecified address ('::') it is replaced by the link- 1057 local address of the sending node in each copy of the flood 1058 multicast, which will be forced to have a loop count of 1. 1059 This feature is for objectives that must be restricted to the 1060 local link. 1062 - The function checks that the ASA registered each objective. 1064 - This call may be repeated whenever any value changes. 1066 * get_flood() 1068 - Input parameters: 1070 asa_nonce (integer) 1072 objective (structure) 1074 - Return parameters: 1076 errorcode (integer) 1078 tagged_objective_list (structure) (if successful) 1080 - This call instructs GRASP to return the given synchronization 1081 objective if it has been flooded and its lifetime has not 1082 expired. 1084 - Since this is essentially a read operation, any ASA can do it. 1085 Therefore the API checks that the ASA is registered but the 1086 objective doesn't need to be registered by the calling ASA. 1088 - The 'tagged_objective_list' parameter is a list of 1089 'tagged_objective' couplets, each one being a copy of the 1090 flooded objective and a coresponding locator. Thus if the same 1091 objective has been flooded by multiple ASAs, the recipient can 1092 distinguish the copies. 1094 - Note that this call is for advanced ASAs. In a simple case, an 1095 ASA can simply call synchronize() in order to get a valid 1096 flooded objective. 1098 * expire_flood() 1100 - Input parameters: 1102 asa_nonce (integer) 1104 tagged_objective (structure) 1106 - Return parameters: 1108 errorcode (integer) 1110 - This is a call that can only be used after a preceding call to 1111 get_flood() by an ASA that is capable of deciding that the 1112 flooded value is stale or invalid. Use with care. 1114 - The 'tagged_objective' parameter is the one to be expired. 1116 2.3.6. Invalid Message Function 1118 * send_invalid() 1120 - Input parameters: 1122 asa_nonce (integer) 1124 session_nonce (structure) 1126 info (bytes) 1128 - Return parameters: 1130 errorcode (integer) 1132 - Sends a GRASP Invalid Message (M_INVALID) message, as described 1133 in [I-D.ietf-anima-grasp]. Should not be used if 1134 end_negotiate() would be sufficient. Note that this message 1135 may be used in response to any unicast GRASP message that the 1136 receiver cannot interpret correctly. In most cases this 1137 message will be generated internally by a GRASP implementation. 1139 'info' = optional diagnostic data. May be raw bytes from the 1140 invalid message. 1142 3. Implementation Status [RFC Editor: please remove] 1144 A prototype open source Python implementation of GRASP, including an 1145 API similar to this document, has been used to verify the concepts 1146 for the threaded model. It may be found at 1147 https://github.com/becarpenter/graspy with associated documentation 1148 and demonstration ASAs. 1150 4. Security Considerations 1152 Security issues for the GRASP protocol are discussed in 1153 [I-D.ietf-anima-grasp]. Authorization of ASAs is a subject for 1154 future study. 1156 The 'asa_nonce' parameter is used in the API as a first line of 1157 defence against a malware process attempting to imitate a 1158 legitimately registered ASA. The 'session_nonce' parameter is used 1159 in the API as a first line of defence against a malware process 1160 attempting to hijack a GRASP session. 1162 5. IANA Considerations 1164 This document makes no request of the IANA. 1166 6. Acknowledgements 1168 Excellent suggestions were made by Ignas Bagdonas, Laurent Ciavaglia, 1169 Toerless Eckert, Guangpeng Li, Michael Richardson, and other 1170 participants in the ANIMA WG. 1172 7. References 1174 7.1. Normative References 1176 [I-D.ietf-anima-grasp] 1177 Bormann, C., Carpenter, B., and B. Liu, "A Generic 1178 Autonomic Signaling Protocol (GRASP)", Work in Progress, 1179 Internet-Draft, draft-ietf-anima-grasp-15, 13 July 2017, 1180 . 1182 7.2. Informative References 1184 [I-D.ietf-anima-autonomic-control-plane] 1185 Eckert, T., Behringer, M., and S. Bjarnason, "An Autonomic 1186 Control Plane (ACP)", Work in Progress, Internet-Draft, 1187 draft-ietf-anima-autonomic-control-plane-24, 9 March 2020, 1188 . 1191 [I-D.ietf-anima-bootstrapping-keyinfra] 1192 Pritikin, M., Richardson, M., Eckert, T., Behringer, M., 1193 and K. Watsen, "Bootstrapping Remote Secure Key 1194 Infrastructures (BRSKI)", Work in Progress, Internet- 1195 Draft, draft-ietf-anima-bootstrapping-keyinfra-41, 8 April 1196 2020, . 1199 [I-D.ietf-anima-reference-model] 1200 Behringer, M., Carpenter, B., Eckert, T., Ciavaglia, L., 1201 and J. Nobre, "A Reference Model for Autonomic 1202 Networking", Work in Progress, Internet-Draft, draft-ietf- 1203 anima-reference-model-10, 22 November 2018, 1204 . 1207 [I-D.liu-anima-grasp-distribution] 1208 Liu, B., Xiao, X., Hecker, A., Jiang, S., and Z. 1209 Despotovic, "Information Distribution in Autonomic 1210 Networking", Work in Progress, Internet-Draft, draft-liu- 1211 anima-grasp-distribution-13, 12 December 2019, 1212 . 1215 Appendix A. Error Codes 1217 This Appendix lists the error codes defined so far, with suggested 1218 symbolic names and corresponding descriptive strings in English. It 1219 is expected that complete API implementations will provide for 1220 localisation of these descriptive strings, and that additional error 1221 codes will be needed according to implementation details. 1223 ok 0 "OK" 1224 declined 1 "Declined" 1225 noReply 2 "No reply" 1226 unspec 3 "Unspecified error" 1227 ASAfull 4 "ASA registry full" 1228 dupASA 5 "Duplicate ASA name" 1229 noASA 6 "ASA not registered" 1230 notYourASA 7 "ASA registered but not by you" 1231 notBoth 8 "Objective cannot support both negotiation 1232 and synchronization" 1233 notDry 9 "Dry-run allowed only with negotiation" 1234 notOverlap 10 "Overlap not supported by this implementation" 1235 objFull 11 "Objective registry full" 1236 objReg 12 "Objective already registered" 1237 notYourObj 13 "Objective not registered by this ASA" 1238 notObj 14 "Objective not found" 1239 notNeg 15 "Objective not negotiable" 1240 noSecurity 16 "No security" 1241 noDiscReply 17 "No reply to discovery" 1242 sockErrNegRq 18 "Socket error sending negotiation request" 1243 noSession 19 "No session" 1244 noSocket 20 "No socket" 1245 loopExhausted 21 "Loop count exhausted" 1246 sockErrNegStep 22 "Socket error sending negotiation step" 1247 noPeer 23 "No negotiation peer" 1248 CBORfail 24 "CBOR decode failure" 1249 invalidNeg 25 "Invalid Negotiate message" 1250 invalidEnd 26 "Invalid end message" 1251 noNegReply 27 "No reply to negotiation step" 1252 noValidStep 28 "No valid reply to negotiation step" 1253 sockErrWait 29 "Socket error sending wait message" 1254 sockErrEnd 30 "Socket error sending end message" 1255 IDclash 31 "Incoming request Session ID clash" 1256 notSynch 32 "Not a synchronization objective" 1257 notFloodDisc 33 "Not flooded and no reply to discovery" 1258 sockErrSynRq 34 "Socket error sending synch request" 1259 noListener 35 "No synch listener" 1260 noSynchReply 36 "No reply to synchronization request" 1261 noValidSynch 37 "No valid reply to synchronization request" 1262 invalidLoc 38 "Invalid locator" 1264 Appendix B. Change log [RFC Editor: Please remove] 1266 draft-ietf-anima-grasp-api-06, 2020-06-07: 1268 * Improved diagram 1270 * Numerous clarifications and layout changes 1271 draft-ietf-anima-grasp-api-05, 2020-05-08: 1273 * Converted to xml2rfc v3 1275 * Editorial fixes. 1277 draft-ietf-anima-grasp-api-04, 2019-10-07: 1279 * Improved discussion of layering, mentioned daemon. 1281 * Added callbacks and improved description of asynchronous 1282 operations. 1284 * Described use case for 'session_nonce'. 1286 * More explanation of 'asa_nonce'. 1288 * Change 'discover' to use 'age_limit' instead of 'flush'. 1290 * Clarified use of 'dry run'. 1292 * Editorial improvements. 1294 draft-ietf-anima-grasp-api-03, 2019-01-21: 1296 * Replaced empty "logic flows" section by "implementation status". 1298 * Minor clarifications. 1300 * Editorial improvements. 1302 draft-ietf-anima-grasp-api-02, 2018-06-30: 1304 * Additional suggestion for event-loop API. 1306 * Discussion of error code values. 1308 draft-ietf-anima-grasp-api-01, 2018-03-03: 1310 * Editorial updates 1312 draft-ietf-anima-grasp-api-00, 2017-12-23: 1314 * WG adoption 1316 * Editorial improvements. 1318 draft-liu-anima-grasp-api-06, 2017-11-24: 1320 * Improved description of event-loop model. 1322 * Changed intended status to Informational. 1324 * Editorial improvements. 1326 draft-liu-anima-grasp-api-05, 2017-10-02: 1328 * Added send_invalid() 1330 draft-liu-anima-grasp-api-04, 2017-06-30: 1332 * Noted that simple nodes might not include the API. 1334 * Minor clarifications. 1336 draft-liu-anima-grasp-api-03, 2017-02-13: 1338 * Changed error return to integers. 1340 * Required all implementations to accept objective values in CBOR. 1342 * Added non-blocking alternatives. 1344 draft-liu-anima-grasp-api-02, 2016-12-17: 1346 * Updated for draft-ietf-anima-grasp-09 1348 draft-liu-anima-grasp-api-02, 2016-09-30: 1350 * Added items for draft-ietf-anima-grasp-07 1352 * Editorial corrections 1354 draft-liu-anima-grasp-api-01, 2016-06-24: 1356 * Updated for draft-ietf-anima-grasp-05 1358 * Editorial corrections 1360 draft-liu-anima-grasp-api-00, 2016-04-04: 1362 * Initial version 1364 Authors' Addresses 1365 Brian Carpenter 1366 School of Computer Science 1367 University of Auckland 1368 PB 92019 1369 Auckland 1142 1370 New Zealand 1372 Email: brian.e.carpenter@gmail.com 1374 Bing Liu (editor) 1375 Huawei Technologies 1376 Q14, Huawei Campus 1377 No.156 Beiqing Road 1378 Hai-Dian District, Beijing 1379 100095 1380 P.R. China 1382 Email: leo.liubing@huawei.com 1384 Wendong Wang 1385 BUPT University 1386 Beijing University of Posts & Telecom. 1387 No.10 Xitucheng Road 1388 Hai-Dian District, Beijing 100876 1389 P.R. China 1391 Email: wdwang@bupt.edu.cn 1393 Xiangyang Gong 1394 BUPT University 1395 Beijing University of Posts & Telecom. 1396 No.10 Xitucheng Road 1397 Hai-Dian District, Beijing 100876 1398 P.R. China 1400 Email: xygong@bupt.edu.cn