idnits 2.17.1 draft-ietf-anima-grasp-api-04.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 2 instances of too long lines in the document, the longest one being 2 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 (October 7, 2019) is 1653 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-20 == Outdated reference: A later version (-45) exists of draft-ietf-anima-bootstrapping-keyinfra-28 == Outdated reference: A later version (-13) exists of draft-liu-anima-grasp-distribution-11 Summary: 1 error (**), 0 flaws (~~), 4 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group B. Carpenter 3 Internet-Draft Univ. of Auckland 4 Intended status: Informational B. Liu, Ed. 5 Expires: April 9, 2020 Huawei Technologies 6 W. Wang 7 X. Gong 8 BUPT University 9 October 7, 2019 11 Generic Autonomic Signaling Protocol Application Program Interface 12 (GRASP API) 13 draft-ietf-anima-grasp-api-04 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 April 9, 2020. 42 Copyright Notice 44 Copyright (c) 2019 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 49 (https://trustee.ietf.org/license-info) in effect on the date of 50 publication of this document. Please review these documents 51 carefully, as they describe your rights and restrictions with respect 52 to this document. Code Components extracted from this document must 53 include Simplified BSD License text as described in Section 4.e of 54 the Trust Legal Provisions and are provided without warranty as 55 described in the Simplified BSD License. 57 Table of Contents 59 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 60 2. GRASP API for ASA . . . . . . . . . . . . . . . . . . . . . . 4 61 2.1. Design Principles . . . . . . . . . . . . . . . . . . . . 4 62 2.2. Asynchronous Operations . . . . . . . . . . . . . . . . . 5 63 2.3. API definition . . . . . . . . . . . . . . . . . . . . . 7 64 2.3.1. Parameters and data structures . . . . . . . . . . . 7 65 2.3.2. Registration . . . . . . . . . . . . . . . . . . . . 11 66 2.3.3. Discovery . . . . . . . . . . . . . . . . . . . . . . 13 67 2.3.4. Negotiation . . . . . . . . . . . . . . . . . . . . . 14 68 2.3.5. Synchronization and Flooding . . . . . . . . . . . . 19 69 2.3.6. Invalid Message Function . . . . . . . . . . . . . . 23 70 3. Implementation Status [RFC Editor: please remove] . . . . . . 24 71 4. Security Considerations . . . . . . . . . . . . . . . . . . . 24 72 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 24 73 6. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 24 74 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 24 75 7.1. Normative References . . . . . . . . . . . . . . . . . . 24 76 7.2. Informative References . . . . . . . . . . . . . . . . . 24 77 Appendix A. Error Codes . . . . . . . . . . . . . . . . . . . . 25 78 Appendix B. Change log [RFC Editor: Please remove] . . . . . . . 26 79 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 28 81 1. Introduction 83 As defined in [I-D.ietf-anima-reference-model], the Autonomic Service 84 Agent (ASA) is the atomic entity of an autonomic function, and it is 85 instantiated on autonomic nodes. When ASAs communicate with each 86 other, they should use the Generic Autonomic Signaling Protocol 87 (GRASP) [I-D.ietf-anima-grasp]. 89 As the following figure shows, a GRASP implementation could contain 90 two major sub-layers. The bottom is the GRASP base protocol module, 91 which is only responsible for sending and receiving GRASP messages 92 and maintaining shared data structures. The upper layer contains 93 some extended functions based upon GRASP basic protocol. For 94 example, [I-D.liu-anima-grasp-distribution] describes a possible 95 extended function. 97 It is desirable that ASAs can be designed as portable user-space 98 programs using a portable API. In many operating systems, the GRASP 99 module will therefore be split into two layers. The top layer is a 100 library that provides the API. The lower layer is a daemon that 101 contains GRASP core functions that are independent of specific ASAs, 102 such as multicast handling and relaying, and common data structures 103 such as the discovery cache. The GRASP API library would need to 104 communicate with the GRASP core via an inter-process communication 105 (IPC) mechanism. The details of this are system-dependent. 107 +----+ +----+ 108 |ASAs| |ASAs| 109 +----+ +----+ 110 | | 111 | GRASP Function API | 112 | | 113 +------------------+ |GRASP API 114 | GRASP Extended | | 115 | Function Modules | | 116 +------------------+ | 117 +------------------------------------------+ 118 | GRASP API Library | 119 | GRASP Modules - - - - - - - - - - - - - | 120 | GRASP Core (Daemon) | 121 +------------------------------------------+ 123 Both the GRASP library and the extended function modules should be 124 available to the ASAs. Thus, there need to be two sub-sets of API. 125 However, since the extended functions are expected to be added in an 126 incremental manner, it is inappropriate to define all the function 127 APIs in a single document. This document only describes the basic 128 GRASP API. 130 Note that a very simple autonomic node might contain only a single 131 ASA in addition to the autonomic infrastructure components described 132 in [I-D.ietf-anima-bootstrapping-keyinfra] and 133 [I-D.ietf-anima-autonomic-control-plane]. Such a node might directly 134 integrate GRASP in its autonomic code and therefore not require this 135 API to be installed. 137 This document gives a conceptual outline of the API. It is not a 138 formal specification for any particular programming language or 139 operating system, and it is expected that details will be clarified 140 in individual implementations. 142 2. GRASP API for ASA 144 2.1. Design Principles 146 The assumption of this document is that any Autonomic Service Agent 147 (ASA) needs to call a GRASP module that handles protocol details 148 (security, sending and listening for GRASP messages, waiting, caching 149 discovery results, negotiation looping, sending and receiving 150 sychronization data, etc.) but understands nothing about individual 151 objectives. The semantics of objectives are unknown to the GRASP 152 module and are handled only by the ASAs. Thus, this is a high level 153 abstract API for use by ASAs. Individual language bindings should be 154 defined in separate documents. 156 An assumption of this API is that ASAs may fall into various classes: 158 o ASAs that only use GRASP for discovery purposes. 160 o ASAs that use GRASP negotiation but only as an initiator (client). 162 o ASAs that use GRASP negotiation but only as a responder. 164 o ASAs that use GRASP negotiation as an initiator or responder. 166 o ASAs that use GRASP synchronization but only as an initiator 167 (recipient). 169 o ASAs that use GRASP synchronization but only as a responder and/or 170 flooder. 172 o ASAs that use GRASP synchronization as an initiator, responder 173 and/or flooder. 175 The API also assumes that one ASA may support multiple objectives. 176 Nothing prevents an ASA from supporting some objectives for 177 synchronization and others for negotiation. 179 The API design assumes that the operating system and programming 180 language provide a mechanism for simultaneous asynchronous 181 operations. This is discussed in detail in Section 2.2. 183 The functions provided by the API do not map one-to-one onto GRASP 184 messages. Rather, they are intended to offer convenient support for 185 message sequences (such as a discovery request followed by responses 186 from several peers, or a negotiation request followed by various 187 possible responses). 189 This is a preliminary version. A few gaps exist: 191 o Authorization of ASAs is out of scope. 193 o User-supplied explicit locators for an objective are not 194 supported. 196 o The Rapid mode of GRASP is not supported. 198 2.2. Asynchronous Operations 200 GRASP includes asynchronous operations and wait states, and its 201 messages are not idempotent, i.e. they may cause incremental changes 202 of state in the recipient ASA. Most ASAs will need to support 203 several simultaneous operations; for example an ASA might need to 204 negotiate one objective with a peer while discovering and 205 synchronizing a different objective with a different peer. 206 Alternatively, an ASA which acts as a resource manager might need to 207 run simultaneous negotiations for a given objective with multiple 208 different peers. Such an ASA must support atomic access to its 209 internal data structures, for example using operating system locks. 211 Thus, both the GRASP core and most ASAs need to support asynchronous 212 operations. Depending on both the operating system and the 213 programming language in use, there are three main techniques for such 214 parallel operations: multi-threading, an event loop structure using 215 polling, and an event loop structure using callback functions. 217 1. In multi-threading, the operating system and language will 218 provide the necessary support for asynchronous operations, 219 including creation of new threads, context switching between 220 threads, queues, locks, and implicit wait states. In this case, 221 all API calls can be treated naturally as synchronous, even if 222 they include wait states, blocking and queueing. Simultaneous 223 operations will each run in their own threads. For example, the 224 discover() call may not return until discovery results have 225 arrived or a timeout has occurred. If the ASA has other work to 226 do, the discover() call must be in a thread of its own. 228 2. In an event loop implementation with polling, blocking calls are 229 not acceptable. Therefore all calls must be non-blocking, and 230 the main loop could support multiple GRASP sessions in parallel 231 by repeatedly polling each one for a change of state. To 232 facilitate this, the API implementation would provide non- 233 blocking versions of all the functions that otherwise involve 234 blocking and queueing. In these calls, a 'noReply' code will be 235 returned by each call instead of blocking, until such time as the 236 event for which it is waiting (or a failure) has occurred. Thus, 237 for example, discover() would return 'noReply' instead of waiting 238 until discovery has succeeded or timed out. The discover() call 239 would be repeated in every cycle of the main loop until it 240 completes. Effectively, it becomes a polling call. 242 3. In an event loop implementation with callbacks, the ASA 243 programmer would provide a callback function for each 244 asynchronous operation, e.g. discovery_received(). This would be 245 called asynchronously when a reply is received or a failure such 246 as a timeout occurs. 248 The following calls involve waiting for a remote operation, so they 249 could use a polling or callback mechanism. In a threaded mechanism, 250 they will usually require to be called in a separate thread: 252 discover() whose callback would be discovery_received(). 254 request_negotiate() whose callback would be 255 negotiate_step_received(). 257 negotiate_step() whose callback would be 258 negotiate_step_received(). 260 listen_negotiate() whose callback would be 261 negotiate_step_received(). 263 synchronize() whose callback would be synchronization_received(). 265 There is nothing in the design of GRASP to prevent the following 266 scenario. Consider an ASA "A" that acts as a resource allocator for 267 some objective. An ASA "B" launches a negotiation with "A" to obtain 268 or release a quantity of the resource. While this negotatition is 269 under way, "B" chooses to launch a second simultaneous negotiation 270 with "A" for a different quantity of the same resource. "A" must 271 therefore conduct two separate negotiation sessions at the same time 272 with the same peer, and must not mix them up. 274 Note that ASAs could be designed to avoid such a scenario, i.e. 275 restricted to exactly one negotiation session at a time for a given 276 objective, but this would be a voluntary restriction not required by 277 the GRASP protocol. In fact it is an assumption of GRASP that an ASA 278 managing a resource may need to conduct multiple parallel 279 negotiations, possibly with the same peer. Therefore, the API design 280 allows for such scenarios. 282 In the callback model, for the scenario just described, the ASAs "A" 283 and "B" will each provide two instances of negotiate_step_received(), 284 one for each session. For this reason, each ASA must be able to 285 distinguish the two sessions, and the peer's IP address is not 286 sufficient for this. It is also not safe to rely on transport port 287 numbers for this, since future variants of GRASP might use shared 288 ports rather than a separate port per session. This is why the GRASP 289 design includes a session identifier. Thus, when necessary, a 290 'session_nonce' parameter is used in the API to distinguish 291 simultaneous GRASP sessions from each other, so that any number of 292 sessions may proceed asynchronously in parallel. 294 In calls where it is used, the 'session_nonce' is an opaque read/ 295 write parameter. On the first call, it is set to a null value, and 296 the API returns a non-null 'session_nonce' value based on the GRASP 297 session identifier. This value must be used in all subsequent calls 298 for the same session, and will be provided as a parameter in the 299 callback functions. By this mechanism, multiple overlapping sessions 300 can be distinguished, both in the ASA and in the GRASP core. The 301 value of the 'session_nonce" is opaque to the ASA. 303 An additional mechanism that might increase efficiency for polling 304 implementations is to add a general call, say notify(), which would 305 check the status of all outstanding operations for the calling ASA 306 and return the session_nonce values for all sessions that have 307 changed state. This would eliminate the need for repeated calls to 308 the individual functions returning a 'noReply'. This call is not 309 described below as the details are likely to be implementation- 310 specific. 312 An implication of the above for all GRASP implementations is that the 313 GRASP core must keep state for each GRASP operation in progress, most 314 likely keyed by the GRASP Session ID and the GRASP source address of 315 the session initiator. Even in a threaded implementation, the GRASP 316 core will need such state internally. The session_nonce parameter 317 exposes this aspect of the implementation. 319 2.3. API definition 321 2.3.1. Parameters and data structures 323 This section describes parameters and data structures used in 324 multiple API calls. 326 2.3.1.1. Errorcode 328 All functions in the API have an unsigned 'errorcode' integer as 329 their return value (the first returned value in languages that allow 330 multiple returned parameters). An errorcode of zero indicates 331 success. Any other value indicates failure of some kind. The first 332 three errorcodes have special importance: 334 1. Declined: used to indicate that the other end has sent a GRASP 335 Negotiation End message (M_END) with a Decline option 336 (O_DECLINE). 338 2. No reply: used in non-blocking calls to indicate that the other 339 end has sent no reply so far (see Section 2.2). 341 3. Unspecified error: used when no more specific error code applies. 343 Appendix A gives a full list of currently suggested error codes, 344 based on implementation experience. While there is no absolute 345 requirement for all implementations to use the same error codes, this 346 is highly recommended for portability of applications. 348 2.3.1.2. Timeout 350 Wherever a 'timeout' parameter appears, it is an integer expressed in 351 milliseconds. If it is zero, the GRASP default timeout 352 (GRASP_DEF_TIMEOUT, see [I-D.ietf-anima-grasp]) will apply. If no 353 response is received before the timeout expires, the call will fail 354 unless otherwise noted. 356 2.3.1.3. Objective 358 An 'objective' parameter is a data structure with the following 359 components: 361 o name (UTF-8 string) - the objective's name 363 o neg (Boolean flag) - True if objective supports negotiation 364 (default False) 366 o synch (Boolean flag) - True if objective supports synchronization 367 (default False) 369 o dry (Boolean flag) - True if objective supports dry-run 370 negotiation (default False) 372 * Note 1: All objectives are assumed to support discovery, so 373 there is no Boolean for that. 375 * Note 2: Only one of 'synch' or 'neg' may be True. 377 * Note 3: 'dry' must not be True unless 'neg' is also True. 379 * Note 4: In a language such as C the preferred implementation 380 may be to represent the Boolean flags as bits in a single byte. 382 o loop_count (integer) - Limit on negotiation steps etc. (default 383 GRASP_DEF_LOOPCT, see [I-D.ietf-anima-grasp]) 385 o value - a specific data structure expressing the value of the 386 objective. The format is language dependent, with the constraint 387 that it can be validly represented in CBOR (default integer = 0). 389 An essential requirement for all language mappings and all 390 implementations is that, regardless of what other options exist 391 for a language-specific represenation of the value, there is 392 always an option to use a CBOR byte string as the value. The API 393 will then wrap this byte string in CBOR Tag 24 for transmission 394 via GRASP, and unwrap it after reception. 396 An example data structure definition for an objective in the C 397 language, assuming the use of a particular CBOR library, is: 399 typedef struct { 400 char *name; 401 uint8_t flags; // flag bits as defined by GRASP 402 int loop_count; 403 int value_size; // size of value in bytes 404 cbor_mutable_data cbor_value; 405 // CBOR bytestring (libcbor/cbor/data.h) 406 } objective; 408 An example data structure definition for an objective in the 409 Python language is: 411 class objective: 412 """A GRASP objective""" 413 def __init__(self, name): 414 self.name = name # Unique name (string) 415 self.negotiate = False # True if objective supports negotiation 416 self.dryrun = False # True if objective supports dry-run neg. 417 self.synch = False # True if objective supports synch 418 self.loop_count = GRASP_DEF_LOOPCT # Default starting value 419 self.value = 0 # Place holder; any valid Python object 421 2.3.1.4. ASA_locator 423 An 'ASA_locator' parameter is a data structure with the following 424 contents: 426 o locator - The actual locator, either an IP address or an ASCII 427 string. 429 o ifi (integer) - The interface identifier index via which this was 430 discovered - probably no use to a normal ASA 432 o expire (system dependent type) - The time on the local system 433 clock when this locator will expire from the cache 435 o is_ipaddress (Boolean) - True if the locator is an IP address 437 o is_fqdn (Boolean) - True if the locator is an FQDN 439 o is_uri (Boolean) - True if the locator is a URI 441 o diverted (Boolean) - True if the locator was discovered via a 442 Divert option 444 o protocol (integer) - Applicable transport protocol (IPPROTO_TCP or 445 IPPROTO_UDP) 447 o port (integer) - Applicable port number 449 2.3.1.5. Tagged_objective 451 A 'tagged_objective' parameter is a data structure with the following 452 contents: 454 o objective - An objective 456 o locator - The ASA_locator associated with the objective, or a null 457 value. 459 2.3.1.6. Asa_nonce 461 Although an authentication and authorization scheme for ASAs has not 462 been defined, the API provides a very simple hook for such a scheme. 463 When an ASA starts up, it registers itself with the GRASP core, which 464 provides it with an opaque nonce that, although not cryptographically 465 protected, would be difficult for a third party to predict. The ASA 466 must present this nonce in future calls. This mechanism will prevent 467 some elementary errors or trivial attacks such as an ASA manipulating 468 an objective it has not registered to use. 470 Thus, in most calls, an 'asa_nonce' parameter is required. It is 471 generated when an ASA first registers with GRASP, and the ASA must 472 then store the asa_nonce and use it in every subsequent GRASP call. 473 Any call in which an invalid nonce is presented will fail. It is an 474 up to 32-bit opaque value (for example represented as a uint32_t, 475 depending on the language). It should be unpredictable; a possible 476 implementation is to use the same mechanism that GRASP uses to 477 generate Session IDs [I-D.ietf-anima-grasp]. Another possible 478 implementation is to hash the name of the ASA with a locally defined 479 secret key. 481 2.3.1.7. Session_nonce 483 In some calls, a 'session_nonce' parameter is required. This is an 484 opaque data structure as far as the ASA is concerned, used to 485 identify calls to the API as belonging to a specific GRASP session 486 (see Section 2.2). In fully threaded implementations this parameter 487 might not be needed, but it is included to act as a session handle if 488 necessary. It will also allow GRASP to detect and ignore malicious 489 calls or calls from timed-out sessions. A possible implementation is 490 to form the nonce from the underlying GRASP Session ID and the source 491 address of the session. 493 2.3.2. Registration 495 These functions are used to register an ASA and the objectives that 496 it supports with the GRASP module. If an authorization model is 497 added to GRASP, it would also be added at this point in the API. 499 o register_asa() 501 Input parameter: 503 name of the ASA (UTF-8 string) 505 Return parameters: 507 errorcode (integer) 509 asa_nonce (integer) (if successful) 511 This initialises state in the GRASP module for the calling 512 entity (the ASA). In the case of success, an 'asa_nonce' is 513 returned which the ASA must present in all subsequent calls. 514 In the case of failure, the ASA has not been authorized and 515 cannot operate. 517 o deregister_asa() 519 Input parameters: 521 asa_nonce (integer) 523 name of the ASA (UTF-8 string) 525 Return parameter: 527 errorcode (integer) 529 This removes all state in the GRASP module for the calling 530 entity (the ASA), and deregisters any objectives it has 531 registered. Note that these actions must also happen 532 automatically if an ASA crashes. 534 Note - the ASA name is strictly speaking redundant in this 535 call, but is present for clarity. 537 o register_objective() 539 Input parameters: 541 asa_nonce (integer) 543 objective (structure) 545 ttl (integer - default GRASP_DEF_TIMEOUT) 547 discoverable (Boolean - default False) 549 overlap (Boolean - default False) 551 local (Boolean - default False) 553 Return parameter: 555 errorcode (integer) 557 This registers an objective that this ASA supports and may 558 modify. The 'objective' becomes a candidate for discovery. 559 However, discovery responses should not be enabled until the 560 ASA calls listen_negotiate() or listen_synchronize(), showing 561 that it is able to act as a responder. The ASA may negotiate 562 the objective or send synchronization or flood data. 563 Registration is not needed if the ASA only wants to receive 564 synchronization or flood data for the objective concerned. 566 The 'ttl' parameter is the valid lifetime (time to live) in 567 milliseconds of any discovery response for this objective. The 568 default value should be the GRASP default timeout 569 (GRASP_DEF_TIMEOUT, see [I-D.ietf-anima-grasp]). 571 If the parameter 'discoverable' is True, the objective is 572 immediately discoverable. This is intended for objectives that 573 are only defined for GRASP discovery, and which do not support 574 negotiation or synchronization. 576 If the parameter 'overlap' is True, more than one ASA may 577 register this objective in the same GRASP instance. 579 If the parameter 'local' is True, discovery must return a link- 580 local address. This feature is for objectives that must be 581 restricted to the local link. 583 This call may be repeated for multiple objectives. 585 o deregister_objective() 587 Input parameters: 589 asa_nonce (integer) 591 objective (structure) 593 Return parameter: 595 errorcode (integer) 597 The 'objective' must have been registered by the calling ASA; 598 if not, this call fails. Otherwise, it removes all state in 599 the GRASP module for the given objective. 601 2.3.3. Discovery 603 o discover() 605 Input parameters: 607 asa_nonce (integer) 609 objective (structure) 611 timeout (integer) 613 age_limit (integer) 615 Return parameters: 617 errorcode (integer) 619 locator_list (structure) 621 This returns a list of discovered 'ASA_locator's for the given 622 objective. Note that this structure includes all the fields 623 described in Section 2.3.1.4. 625 If the parameter 'age_limit' is greater than zero, any locally 626 cached locators for the objective whose remaining lifetime in 627 milliseconds is less than or equal to 'age_limit' are deleted 628 first. Thus 'age_limit' = 0 will flush all entries. 630 If the parameter 'timeout' is zero, any remaining locally 631 cached locators for the objective are returned immediately and 632 no other action is taken. (Thus, a call with 'age_limit' and 633 'timeout' both equal to zero is pointless.) 635 If the parameter 'timeout' is greater than zero, GRASP 636 discovery is performed, and all results obtained before the 637 timeout in milliseconds expires are returned. If no results 638 are obtained, an empty list is returned after the timeout. 639 That is not an error condition. 641 Threaded implementation: This should be called in a separate 642 thread if asynchronous operation is required. 644 Event loop implementation: An additional read/write 645 'session_nonce' parameter is used. A callback may be used in 646 the case of a non-zero tiemout. 648 2.3.4. Negotiation 650 o request_negotiate() 652 Input parameters: 654 asa_nonce (integer) 656 objective (structure) 658 peer (ASA_locator) 660 timeout (integer) 662 Return parameters: 664 errorcode (integer) 666 session_nonce (structure) (if successful) 668 proffered_objective (structure) (if successful) 669 reason (string) (if negotiation declined) 671 This function opens a negotiation session. The 'objective' 672 parameter must include the requested value, and its loop count 673 should be set to a suitable value by the ASA. If not, the 674 GRASP default will apply. 676 Note that a given negotiation session may or may not be a dry- 677 run negotiation; the two modes must not be mixed in a single 678 session. 680 The 'peer' parameter is the target node; it must be an 681 'ASA_locator' as returned by discover(). If the peer is null, 682 GRASP discovery is performed first. 684 If the 'errorcode' return parameter is 0, the negotiation has 685 successfully started. There are then two cases: 687 1. The 'session_nonce' parameter is null. In this case the 688 negotiation has succeeded (the peer has accepted the 689 request). The returned 'proffered_objective' contains the 690 value accepted by the peer. 692 2. The 'session_nonce' parameter is not null. In this case 693 negotiation must continue. The returned 694 'proffered_objective' contains the first value proffered by 695 the negotiation peer. Note that this instance of the 696 objective must be used in the subsequent negotiation call 697 because it also contains the current loop count. The 698 'session_nonce' must be presented in all subsequent 699 negotiation steps. 701 This function must be followed by calls to 'negotiate_step' 702 and/or 'negotiate_wait' and/or 'end_negotiate' until the 703 negotiation ends. 'request_negotiate' may then be called 704 again to start a new negotation. 706 If the 'errorcode' parameter has the value 1 ('declined'), the 707 negotiation has been declined by the peer (M_END and O_DECLINE 708 features of GRASP). The 'reason' string is then available for 709 information and diagnostic use, but it may be a null string. 710 For this and any other error code, an exponential backoff is 711 recommended before any retry. 713 Threaded implementation: This should be called in a separate 714 thread if asynchronous operation is required. 716 Event loop implementation: The 'session_nonce' parameter is 717 used in read/write mode. 719 Use of dry run mode: This must be consistent within a GRASP 720 session. The state of the 'dry' flag in the initial 721 request_negotiate() call must be the same in all subsequent 722 negotiation steps of the same session. The semantics of the 723 dry run mode are built into the ASA; GRASP merely carries the 724 flag bit. 726 Special note for the ACP infrastructure ASA: It is likely that 727 this ASA will need to discover and negotiate with its peers in 728 each of its on-link neighbors. It will therefore need to know 729 not only the link-local IP address but also the physical 730 interface and transport port for connecting to each neighbor. 731 One implementation approach to this is to include these details 732 in the 'session_nonce' data structure, which is opaque to 733 normal ASAs. 735 o listen_negotiate() 737 Input parameters: 739 asa_nonce (integer) 741 objective (structure) 743 Return parameters: 745 errorcode (integer) 747 session_nonce (structure) (if successful) 749 requested_objective (structure) (if successful) 751 This function instructs GRASP to listen for negotiation 752 requests for the given 'objective'. It also enables discovery 753 responses for the objective. 755 Threaded implementation: It will block waiting for an incoming 756 request, so should be called in a separate thread if 757 asynchronous operation is required. If the ASA supports 758 multiple simultaneous transactions, a new thread must be 759 spawned for each new session. 761 Event loop implementation: A read/write 'session_nonce' 762 parameter is used. If the ASA supports multiple simultaneous 763 transactions, a new event must be inserted in the event loop 764 for each new session. 766 Unless there is an unexpected failure, this call only returns 767 after an incoming negotiation request. When it does so, 768 'requested_objective' contains the first value requested by the 769 negotiation peer. Note that this instance of the objective 770 must be used in the subsequent negotiation call because it also 771 contains the current loop count. The 'session_nonce' must be 772 presented in all subsequent negotiation steps. 774 This function must be followed by calls to 'negotiate_step' 775 and/or 'negotiate_wait' and/or 'end_negotiate' until the 776 negotiation ends. 'listen_negotiate' may then be called again 777 to await a new negotation. 779 If an ASA is capable of handling multiple negotiations 780 simultaneously, it may call 'listen_negotiate' simultaneously 781 from multiple threads. The API and GRASP implementation must 782 support re-entrant use of the listening state and the 783 negotiation calls. Simultaneous sessions will be distinguished 784 by the threads themselves, the GRASP Session IDs, and the 785 underlying unicast transport sockets. 787 o stop_listen_negotiate() 789 Input parameters: 791 asa_nonce (integer) 793 objective (structure) 795 Return parameter: 797 errorcode (integer) 799 Instructs GRASP to stop listening for negotiation requests for 800 the given objective, i.e., cancels 'listen_negotiate'. 802 Threaded implementation: Must be called from a different thread 803 than 'listen_negotiate'. 805 Event loop implementation: no special considerations. 807 o negotiate_step() 809 Input parameters: 811 asa_nonce (integer) 813 session_nonce (structure) 815 objective (structure) 817 timeout (integer) 819 Return parameters: 821 Exactly as for 'request_negotiate' 823 Executes the next negotation step with the peer. The 824 'objective' parameter contains the next value being proffered 825 by the ASA in this step. 827 Threaded implementation: Called in the same thread as the 828 preceding 'request_negotiate' or 'listen_negotiate', with the 829 same value of 'session_nonce'. 831 Event loop implementation: Must use the same value of 832 'session_nonce' returned by the preceding 'request_negotiate' 833 or 'listen_negotiate'. 835 o negotiate_wait() 837 Input parameters: 839 asa_nonce (integer) 841 session_nonce (structure) 843 timeout (integer) 845 Return parameters: 847 errorcode (integer) 849 Delay negotiation session by 'timeout' milliseconds, thereby 850 extending the original timeout. This function simply triggers 851 a GRASP Confirm Waiting message. 853 Threaded implementation: Called in the same thread as the 854 preceding 'request_negotiate' or 'listen_negotiate', with the 855 same value of 'session_nonce'. 857 Event loop implementation: Must use the same value of 858 'session_nonce' returned by the preceding 'request_negotiate' 859 or 'listen_negotiate'. 861 o end_negotiate() 863 Input parameters: 865 asa_nonce (integer) 867 session_nonce (structure) 869 reply (Boolean) 871 reason (UTF-8 string) 873 Return parameters: 875 errorcode (integer) 877 End the negotiation session. 879 'reply' = True for accept (successful negotiation), False for 880 decline (failed negotiation). 882 'reason' = optional string describing reason for decline. 884 Threaded implementation: Called in the same thread as the 885 preceding 'request_negotiate' or 'listen_negotiate', with the 886 same value of 'session_nonce'. 888 Event loop implementation: Must use the same value of 889 'session_nonce' returned by the preceding 'request_negotiate' 890 or 'listen_negotiate'. 892 2.3.5. Synchronization and Flooding 894 o synchronize() 896 Input parameters: 898 asa_nonce (integer) 900 objective (structure) 902 peer (ASA_locator) 904 timeout (integer) 906 Return parameters: 908 errorcode (integer) 910 objective (structure) (if successful) 912 This call requests the synchronized value of the given 913 'objective'. 915 Since this is essentially a read operation, any ASA can do it. 916 Therefore the API checks that the ASA is registered but the 917 objective doesn't need to be registered by the calling ASA. 919 If the objective was already flooded, the flooded value is 920 returned immediately in the 'result' parameter. In this case, 921 the 'source' and 'timeout' are ignored. 923 Otherwise, synchronization with a discovered ASA is performed. 924 The 'peer' parameter is an 'ASA_locator' as returned by 925 discover(). If 'peer' is null, GRASP discovery is performed 926 first. 928 This call should be repeated whenever the latest value is 929 needed. 931 Threaded implementation: Call in a separate thread if 932 asynchronous operation is required. 934 Event loop implementation: An additional read/write 935 'session_nonce' parameter is used. 937 Since this is essentially a read operation, any ASA can use it. 938 Therefore GRASP checks that the calling ASA is registered but 939 the objective doesn't need to be registered by the calling ASA. 941 In the case of failure, an exponential backoff is recommended 942 before retrying. 944 o listen_synchronize() 946 Input parameters: 948 asa_nonce (integer) 950 objective (structure) 952 Return parameters: 954 errorcode (integer) 956 This instructs GRASP to listen for synchronization requests for 957 the given objective, and to respond with the value given in the 958 'objective' parameter. It also enables discovery responses for 959 the objective. 961 This call is non-blocking and may be repeated whenever the 962 value changes. 964 o stop_listen_synchronize() 966 Input parameters: 968 asa_nonce (integer) 970 objective (structure) 972 Return parameters: 974 errorcode (integer) 976 This call instructs GRASP to stop listening for synchronization 977 requests for the given 'objective', i.e. it cancels a previous 978 listen_synchronize. 980 o flood() 982 Input parameters: 984 asa_nonce (integer) 986 ttl (integer) 988 tagged_objective_list (structure) 990 Return parameters: 992 errorcode (integer) 994 This call instructs GRASP to flood the given synchronization 995 objective(s) and their value(s) and associated locator(s) to 996 all GRASP nodes. 998 The 'ttl' parameter is the valid lifetime (time to live) of the 999 flooded data in milliseconds (0 = infinity) 1000 The 'tagged_objective_list' parameter is a list of one or more 1001 'tagged_objective' couplets. The 'locator' parameter that tags 1002 each objective is normally null but may be a valid 1003 'ASA_locator'. Infrastructure ASAs needing to flood an 1004 {address, protocol, port} 3-tuple with an objective create an 1005 ASA_locator object to do so. If the IP address in that locator 1006 is the unspecified address ('::') it is replaced by the link- 1007 local address of the sending node in each copy of the flood 1008 multicast, which will be forced to have a loop count of 1. 1009 This feature is for objectives that must be restricted to the 1010 local link. 1012 The function checks that the ASA registered each objective. 1014 This call may be repeated whenever any value changes. 1016 o get_flood() 1018 Input parameters: 1020 asa_nonce (integer) 1022 objective (structure) 1024 Return parameters: 1026 errorcode (integer) 1028 tagged_objective_list (structure) (if successful) 1030 This call instructs GRASP to return the given synchronization 1031 objective if it has been flooded and its lifetime has not 1032 expired. 1034 Since this is essentially a read operation, any ASA can do it. 1035 Therefore the API checks that the ASA is registered but the 1036 objective doesn't need to be registered by the calling ASA. 1038 The 'tagged_objective_list' parameter is a list of 1039 'tagged_objective' couplets, each one being a copy of the 1040 flooded objective and a coresponding locator. Thus if the same 1041 objective has been flooded by multiple ASAs, the recipient can 1042 distinguish the copies. 1044 Note that this call is for advanced ASAs. In a simple case, an 1045 ASA can simply call synchronize() in order to get a valid 1046 flooded objective. 1048 o expire_flood() 1050 Input parameters: 1052 asa_nonce (integer) 1054 tagged_objective (structure) 1056 Return parameters: 1058 errorcode (integer) 1060 This is a call that can only be used after a preceding call to 1061 get_flood() by an ASA that is capable of deciding that the 1062 flooded value is stale or invalid. Use with care. 1064 The 'tagged_objective' parameter is the one to be expired. 1066 2.3.6. Invalid Message Function 1068 o send_invalid() 1070 Input parameters: 1072 asa_nonce (integer) 1074 session_nonce (structure) 1076 info (bytes) 1078 Return parameters: 1080 errorcode (integer) 1082 Sends a GRASP Invalid Message (M_INVALID) message, as described 1083 in [I-D.ietf-anima-grasp]. Should not be used if 1084 end_negotiate() would be sufficient. Note that this message 1085 may be used in response to any unicast GRASP message that the 1086 receiver cannot interpret correctly. In most cases this 1087 message will be generated internally by a GRASP implementation. 1089 'info' = optional diagnostic data. May be raw bytes from the 1090 invalid message. 1092 3. Implementation Status [RFC Editor: please remove] 1094 A prototype open source Python implementation of GRASP, including an 1095 API similar to this document, has been used to verify the concepts 1096 for the threaded model. It may be found at 1097 with associated documentation 1098 and demonstration ASAs. 1100 4. Security Considerations 1102 Security issues for the GRASP protocol are discussed in 1103 [I-D.ietf-anima-grasp]. Authorization of ASAs is a subject for 1104 future study. 1106 The 'asa_nonce' parameter is used in the API as a first line of 1107 defence against a malware process attempting to imitate a 1108 legitimately registered ASA. The 'session_nonce' parameter is used 1109 in the API as a first line of defence against a malware process 1110 attempting to hijack a GRASP session. 1112 5. IANA Considerations 1114 This document currently makes no request of the IANA. 1116 Open question: Do we need an IANA registry for the error codes? 1118 6. Acknowledgements 1120 Excellent suggestions were made by Ignas Bagdonas, Toerless Eckert, 1121 Guangpeng Li, Michael Richardson, and other participants in the ANIMA 1122 WG. 1124 7. References 1126 7.1. Normative References 1128 [I-D.ietf-anima-grasp] 1129 Bormann, C., Carpenter, B., and B. Liu, "A Generic 1130 Autonomic Signaling Protocol (GRASP)", draft-ietf-anima- 1131 grasp-15 (work in progress), July 2017. 1133 7.2. Informative References 1135 [I-D.ietf-anima-autonomic-control-plane] 1136 Eckert, T., Behringer, M., and S. Bjarnason, "An Autonomic 1137 Control Plane (ACP)", draft-ietf-anima-autonomic-control- 1138 plane-20 (work in progress), July 2019. 1140 [I-D.ietf-anima-bootstrapping-keyinfra] 1141 Pritikin, M., Richardson, M., Eckert, T., Behringer, M., 1142 and K. Watsen, "Bootstrapping Remote Secure Key 1143 Infrastructures (BRSKI)", draft-ietf-anima-bootstrapping- 1144 keyinfra-28 (work in progress), September 2019. 1146 [I-D.ietf-anima-reference-model] 1147 Behringer, M., Carpenter, B., Eckert, T., Ciavaglia, L., 1148 and J. Nobre, "A Reference Model for Autonomic 1149 Networking", draft-ietf-anima-reference-model-10 (work in 1150 progress), November 2018. 1152 [I-D.liu-anima-grasp-distribution] 1153 Liu, B., Xiao, X., Jiang, S., Hecker, A., and Z. 1154 Despotovic, "Information Distribution in Autonomic 1155 Networking", draft-liu-anima-grasp-distribution-11 (work 1156 in progress), July 2019. 1158 Appendix A. Error Codes 1160 This Appendix lists the error codes defined so far, with suggested 1161 symbolic names and corresponding descriptive strings in English. It 1162 is expected that complete API implementations will provide for 1163 localisation of these descriptive strings, and that additional error 1164 codes will be needed according to implementation details. 1166 An open issue for these values is whether there is an advantage in 1167 aligning them with existing error codes in the socket API, where the 1168 meanings coincide, and using different values otherwise. This is to 1169 be balanced against the advantage of having a compact and completely 1170 portable set of error codes for GRASP alone. 1172 ok 0 "OK" 1173 declined 1 "Declined" 1174 noReply 2 "No reply" 1175 unspec 3 "Unspecified error" 1176 ASAfull 4 "ASA registry full" 1177 dupASA 5 "Duplicate ASA name" 1178 noASA 6 "ASA not registered" 1179 notYourASA 7 "ASA registered but not by you" 1180 notBoth 8 "Objective cannot support both negotiation 1181 and synchronization" 1182 notDry 9 "Dry-run allowed only with negotiation" 1183 notOverlap 10 "Overlap not supported by this implementation" 1184 objFull 11 "Objective registry full" 1185 objReg 12 "Objective already registered" 1186 notYourObj 13 "Objective not registered by this ASA" 1187 notObj 14 "Objective not found" 1188 notNeg 15 "Objective not negotiable" 1189 noSecurity 16 "No security" 1190 noDiscReply 17 "No reply to discovery" 1191 sockErrNegRq 18 "Socket error sending negotiation request" 1192 noSession 19 "No session" 1193 noSocket 20 "No socket" 1194 loopExhausted 21 "Loop count exhausted" 1195 sockErrNegStep 22 "Socket error sending negotiation step" 1196 noPeer 23 "No negotiation peer" 1197 CBORfail 24 "CBOR decode failure" 1198 invalidNeg 25 "Invalid Negotiate message" 1199 invalidEnd 26 "Invalid end message" 1200 noNegReply 27 "No reply to negotiation step" 1201 noValidStep 28 "No valid reply to negotiation step" 1202 sockErrWait 29 "Socket error sending wait message" 1203 sockErrEnd 30 "Socket error sending end message" 1204 IDclash 31 "Incoming request Session ID clash" 1205 notSynch 32 "Not a synchronization objective" 1206 notFloodDisc 33 "Not flooded and no reply to discovery" 1207 sockErrSynRq 34 "Socket error sending synch request" 1208 noListener 35 "No synch listener" 1209 noSynchReply 36 "No reply to synchronization request" 1210 noValidSynch 37 "No valid reply to synchronization request" 1211 invalidLoc 38 "Invalid locator" 1213 Appendix B. Change log [RFC Editor: Please remove] 1215 draft-ietf-anima-grasp-api-04, 2019-10-07: 1217 Improved discussion of layering, mentioned daemon. 1219 Added callbacks and improved description of asynchronous operations. 1221 Described use case for 'session_nonce'. 1223 More explanation of 'asa_nonce'. 1225 Change 'discover' to use 'age_limit' instead of 'flush'. 1227 Clarified use of 'dry run'. 1229 Editorial improvements. 1231 draft-ietf-anima-grasp-api-03, 2019-01-21: 1233 Replaced empty "logic flows" section by "implementation status". 1235 Minor clarifications. 1237 Editorial improvements. 1239 draft-ietf-anima-grasp-api-02, 2018-06-30: 1241 Additional suggestion for event-loop API. 1243 Discussion of error code values. 1245 draft-ietf-anima-grasp-api-01, 2018-03-03: 1247 Editorial updates 1249 draft-ietf-anima-grasp-api-00, 2017-12-23: 1251 WG adoption 1253 Editorial improvements. 1255 draft-liu-anima-grasp-api-06, 2017-11-24: 1257 Improved description of event-loop model. 1259 Changed intended status to Informational. 1261 Editorial improvements. 1263 draft-liu-anima-grasp-api-05, 2017-10-02: 1265 Added send_invalid() 1267 draft-liu-anima-grasp-api-04, 2017-06-30: 1269 Noted that simple nodes might not include the API. 1271 Minor clarifications. 1273 draft-liu-anima-grasp-api-03, 2017-02-13: 1275 Changed error return to integers. 1277 Required all implementations to accept objective values in CBOR. 1279 Added non-blocking alternatives. 1281 draft-liu-anima-grasp-api-02, 2016-12-17: 1283 Updated for draft-ietf-anima-grasp-09 1285 draft-liu-anima-grasp-api-02, 2016-09-30: 1287 Added items for draft-ietf-anima-grasp-07 1289 Editorial corrections 1291 draft-liu-anima-grasp-api-01, 2016-06-24: 1293 Updated for draft-ietf-anima-grasp-05 1295 Editorial corrections 1297 draft-liu-anima-grasp-api-00, 2016-04-04: 1299 Initial version 1301 Authors' Addresses 1303 Brian Carpenter 1304 Department of Computer Science 1305 University of Auckland 1306 PB 92019 1307 Auckland 1142 1308 New Zealand 1310 Email: brian.e.carpenter@gmail.com 1311 Bing Liu (editor) 1312 Huawei Technologies 1313 Q14, Huawei Campus 1314 No.156 Beiqing Road 1315 Hai-Dian District, Beijing 100095 1316 P.R. China 1318 Email: leo.liubing@huawei.com 1320 Wendong Wang 1321 BUPT University 1322 Beijing University of Posts & Telecom. 1323 No.10 Xitucheng Road 1324 Hai-Dian District, Beijing 100876 1325 P.R. China 1327 Email: wdwang@bupt.edu.cn 1329 Xiangyang Gong 1330 BUPT University 1331 Beijing University of Posts & Telecom. 1332 No.10 Xitucheng Road 1333 Hai-Dian District, Beijing 100876 1334 P.R. China 1336 Email: xygong@bupt.edu.cn