| <?xml version="1.0"?> |
| <?xml-stylesheet type="text/xsl" href="amqp.xsl"?> |
| |
| <!-- |
| Copyright Notice |
| ================ |
| (c) Copyright Bank of America, N.A., Barclays Bank PLC, Cisco Systems, Credit Suisse, Deutsche |
| Boerse, Envoy Technologies Inc., Goldman Sachs, HCL Technologies Ltd, IIT Software GmbH, iMatix |
| Corporation, INETCO Systems Limited, Informatica Corporation, JPMorgan Chase & Co., Kaazing |
| Corporation, N.A, Microsoft Corporation, my-Channels, Novell, Progress Software, Red Hat Inc., |
| Software AG, Solace Systems Inc., StormMQ Ltd., Tervela Inc., TWIST Process Innovations Ltd, |
| VMware, Inc., and WS02 Inc. |
| 2006-2011. All rights reserved. |
| |
| License |
| ======= |
| |
| Bank of America, N.A., Barclays Bank PLC, Cisco Systems, Credit Suisse, Deutsche Boerse, Goldman |
| Sachs, HCL Technologies Ltd, IIT Software GmbH, INETCO Systems Limited, Informatica Corporation, |
| JPMorgan Chase & Co., Kaazing Corporation, N.A, Microsoft Corporation, my-Channels, Novell, |
| Progress Software, Red Hat Inc., Software AG, Solace Systems Inc., StormMQ Ltd., Tervela Inc., |
| TWIST Process Innovations Ltd, VMware, Inc., and WS02 Inc. (collectively, the "Authors") each |
| hereby grants to you a worldwide, perpetual, royalty-free, nontransferable, nonexclusive license |
| to (i) copy, display, distribute and implement the Advanced Message Queuing Protocol ("AMQP") |
| Specification and (ii) the Licensed Claims that are held by the Authors, all for the purpose of |
| implementing the Advanced Message Queuing Protocol Specification. Your license and any rights |
| under this Agreement will terminate immediately without notice from any Author if you bring any |
| claim, suit, demand, or action related to the Advanced Message Queuing Protocol Specification |
| against any Author. Upon termination, you shall destroy all copies of the Advanced Message Queuing |
| Protocol Specification in your possession or control. |
| |
| As used hereunder, "Licensed Claims" means those claims of a patent or patent application, |
| throughout the world, excluding design patents and design registrations, owned or controlled, or |
| that can be sublicensed without fee and in compliance with the requirements of this Agreement, by |
| an Author or its affiliates now or at any future time and which would necessarily be infringed by |
| implementation of the Advanced Message Queuing Protocol Specification. A claim is necessarily |
| infringed hereunder only when it is not possible to avoid infringing it because there is no |
| plausible non-infringing alternative for implementing the required portions of the Advanced |
| Message Queuing Protocol Specification. Notwithstanding the foregoing, Licensed Claims shall not |
| include any claims other than as set forth above even if contained in the same patent as Licensed |
| Claims; or that read solely on any implementations of any portion of the Advanced Message Queuing |
| Protocol Specification that are not required by the Advanced Message Queuing Protocol |
| Specification, or that, if licensed, would require a payment of royalties by the licensor to |
| unaffiliated third parties. Moreover, Licensed Claims shall not include (i) any enabling |
| technologies that may be necessary to make or use any Licensed Product but are not themselves |
| expressly set forth in the Advanced Message Queuing Protocol Specification (e.g., semiconductor |
| manufacturing technology, compiler technology, object oriented technology, networking technology, |
| operating system technology, and the like); or (ii) the implementation of other published |
| standards developed elsewhere and merely referred to in the body of the Advanced Message Queuing |
| Protocol Specification, or (iii) any Licensed Product and any combinations thereof the purpose or |
| function of which is not required for compliance with the Advanced Message Queuing Protocol |
| Specification. For purposes of this definition, the Advanced Message Queuing Protocol |
| Specification shall be deemed to include both architectural and interconnection requirements |
| essential for interoperability and may also include supporting source code artifacts where such |
| architectural, interconnection requirements and source code artifacts are expressly identified as |
| being required or documentation to achieve compliance with the Advanced Message Queuing Protocol |
| Specification. |
| |
| As used hereunder, "Licensed Products" means only those specific portions of products (hardware, |
| software or combinations thereof) that implement and are compliant with all relevant portions of |
| the Advanced Message Queuing Protocol Specification. |
| |
| The following disclaimers, which you hereby also acknowledge as to any use you may make of the |
| Advanced Message Queuing Protocol Specification: |
| |
| THE ADVANCED MESSAGE QUEUING PROTOCOL SPECIFICATION IS PROVIDED "AS IS," AND THE AUTHORS MAKE NO |
| REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS |
| OF THE ADVANCED MESSAGE QUEUING PROTOCOL SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE |
| IMPLEMENTATION OF THE ADVANCED MESSAGE QUEUING PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD |
| PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. |
| |
| THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL |
| DAMAGES ARISING OUT OF OR RELATING TO ANY USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED |
| MESSAGE QUEUING PROTOCOL SPECIFICATION. |
| |
| The name and trademarks of the Authors may NOT be used in any manner, including advertising or |
| publicity pertaining to the Advanced Message Queuing Protocol Specification or its contents |
| without specific, written prior permission. Title to copyright in the Advanced Message Queuing |
| Protocol Specification will at all times remain with the Authors. |
| |
| No other rights are granted by implication, estoppel or otherwise. |
| |
| Upon termination of your license or rights under this Agreement, you shall destroy all copies of |
| the Advanced Message Queuing Protocol Specification in your possession or control. |
| |
| Trademarks |
| ========== |
| "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the Octagon Symbol are |
| trademarks of JPMorgan Chase & Co. |
| |
| RED HAT is a registered trademarks of Red Hat, Inc. in the US and other countries. |
| |
| Other company, product, or service names may be trademarks or service marks of others. |
| |
| Link to full AMQP specification: |
| ================================= |
| http://www.amqp.org/confluence/display/AMQP/AMQP+Specification |
| --> |
| |
| <!DOCTYPE amqp SYSTEM "amqp.dtd"> |
| |
| <amqp xmlns="http://www.amqp.org/schema/amqp.xsd" |
| name="transport" label="working version"> |
| |
| <!-- == Section: transport =================================================================== --> |
| |
| <section name="transport" label="transport overview"> |
| <doc> |
| <p> |
| The AMQP Network consists of <term>Nodes</term> connected via <term>Links</term>. Nodes are |
| named entities responsible for the safe storage and/or delivery of <term>Messages</term>. |
| Messages can originate from, terminate at, or be relayed by Nodes. |
| </p> |
| |
| <p> |
| A Link is a unidirectional route between two Nodes. Links attach to a Node at |
| a <term>Terminus</term>. There are two kinds of Terminus: <term>Sources</term> |
| and <term>Targets</term>. A Terminus is responsible for tracking the state of a particular |
| stream of incoming or outgoing messages. Sources track outgoing messages and Targets track |
| incoming messages. Messages may only travel along a Link if they meet the entry criteria at |
| the Source. |
| </p> |
| |
| <p> |
| As a Message travels through the AMQP network, the responsibility for safe storage and |
| delivery of the Message is transferred between the Nodes it encounters. The Link Protocol |
| (defined in <xref name="links"/> ) manages the transfer of responsibility between the Source |
| and Target. |
| </p> |
| |
| <picture> |
| <![CDATA[ |
| +------------+ +------------+ |
| / Node A \ / Node B \ |
| +----------------+ +--filter +----------------+ |
| | | / | | |
| | MSG_3 <MSG_1> | _/ _ | MSG_1 | |
| | |(_)------------------>(_)| | |
| | <MSG_2> MSG_4 | | | | MSG_2 | |
| | | | Link(Src,Tgt) | | | |
| +----------------+ | | +----------------+ |
| | | |
| Src Tgt |
| |
| |
| Key: <MSG_n> = old location of MSG_n |
| ]]> |
| </picture> |
| |
| <p> |
| Nodes exist within a <term>Container</term>, and each Container may hold many Nodes. |
| Examples of AMQP Nodes are Producers, Consumers, and Queues. Producers and Consumers are the |
| elements within a client Application that generate and process Messages. Queues are entities |
| within a Broker that store and forward Messages. Examples of containers are Brokers and |
| Client Applications. |
| </p> |
| |
| <picture> |
| <![CDATA[ |
| +---------------+ +----------+ |
| | <<Container>> | 1..1 0..n | <<Node>> | |
| |---------------|<>-------------------->|----------| |
| | container-id | | name | |
| +---------------+ +----------+ |
| /_\ /_\ |
| | | |
| | | |
| +-----+-----+ +----------+----------+ |
| | | | | | |
| | | | | | |
| +--------+ +--------+ +----------+ +----------+ +-------+ |
| | Broker | | Client | | Producer | | Consumer | | Queue | |
| |--------| |--------| |----------| |----------| |-------| |
| | | | | | | | | | | |
| +--------+ +--------+ +----------+ +----------+ +-------+ |
| ]]> |
| </picture> |
| |
| <p> |
| The AMQP Transport Specification defines a peer-to-peer protocol for transferring Messages |
| between Nodes in the AMQP network. This portion of the specification is not concerned with |
| the internal workings of any sort of Node, and only deals with the mechanics of |
| unambiguously transferring a Message from one Node to another. |
| </p> |
| |
| <p> |
| Containers communicate via <term>Connections</term>. An AMQP Connection consists of a |
| full-duplex, reliably ordered sequence of <term>Frames</term>. The precise requirement for a |
| Connection is that if the n<sup>th</sup> Frame arrives, all Frames prior to n MUST also have |
| arrived. It is assumed Connections are transient and may fail for a variety of reasons |
| resulting in the loss of an unknown number of frames, but they are still subject to the |
| aforementioned ordered reliability criteria. This is similar to the guarantee that TCP or |
| SCTP provides for byte streams, and the specification defines a framing system used to parse |
| a byte stream into a sequence of Frames for use in establishing an AMQP Connection (see |
| <xref name="framing"/>). |
| </p> |
| |
| <p> |
| An AMQP Connection is divided into a negotiated number of independent unidirectional |
| <term>Channels</term>. Each Frame is marked with the Channel number indicating its parent |
| Channel, and the Frame sequence for each Channel is multiplexed into a single Frame sequence |
| for the Connection. |
| </p> |
| |
| <p> |
| An AMQP <term>Session</term> correlates two unidirectional Channels to form a bidirectional, |
| sequential conversation between two Containers. A single Connection may have multiple |
| independent Sessions active simultaneously, up to the negotiated Channel limit. Both |
| Connections and Sessions are modeled by each peer as <term>endpoints</term> that store local |
| and last known remote state regarding the Connection or Session in question. |
| </p> |
| |
| <picture title="Session & Connection Endpoints"> |
| <![CDATA[ |
| Session<------+ +------>Session |
| (ICH=1, OCH=1) | | (ICH=1, OCH=1) |
| \|/ \|/ |
| Session<--> Connection <---------> Connection <-->Session |
| (ICH=2, OCH=3) /|\ /|\ (ICH=3, OCH=2) |
| | | |
| Session<------+ +------>Session |
| (ICH=3, OCH=2) (ICH=2, OCH=3) |
| |
| Key: ICH -> Input Channel, OCH -> Output Channel |
| ]]> |
| </picture> |
| |
| <p> |
| Sessions provide the context for communication between Sources and Targets. A <term>Link |
| Endpoint</term> associates a Terminus with a <term>Session Endpoint</term>. Within a |
| Session, the Link Protocol (defined in <xref name="links"/>) is used to establish Links |
| between Sources and Targets and to transfer Messages across them. A single Session may be |
| simultaneously associated with any number of Links. |
| </p> |
| |
| <picture><![CDATA[ |
| +-------------+ |
| | Link | Message Transport |
| +-------------+ (Node to Node) |
| | name | |
| | source | |
| | target | |
| | timeout | |
| +-------------+ |
| /|\ 0..n |
| | |
| | |
| | |
| \|/ 0..1 |
| +------------+ |
| | Session | Frame Transport |
| +------------+ (Container to Container) |
| | name | |
| +------------+ |
| /|\ 0..n |
| | |
| | |
| | |
| \|/ 1..1 |
| +------------+ |
| | Connection | Frame Transport |
| +------------+ (Container to Container) |
| | principal | |
| +------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| A Frame is the unit of work carried on the wire. Connections have a negotiated maximum frame |
| size allowing byte streams to be easily defragmented into complete frame bodies representing |
| the independently parsable units formally defined in <xref name="performatives"/>. The |
| following table lists all frame bodies and defines which endpoints handle them. |
| </p> |
| |
| <picture><![CDATA[ |
| Frame Connection Session Link |
| ======================================== |
| open H |
| begin I H |
| attach I H |
| flow I H |
| transfer I H |
| disposition I H |
| detach I H |
| end I H |
| close H |
| ---------------------------------------- |
| |
| Key: |
| H: handled by the endpoint |
| |
| I: intercepted (endpoint examines |
| the frame, but delegates |
| further processing to another |
| endpoint) |
| ]]> |
| </picture> |
| </doc> |
| </section> |
| |
| <section name="version-negotiation" title="Version Negotiation" |
| label="definition of version negotiation steps"> |
| <doc > |
| <p> |
| Prior to sending any Frames on a Connection, each peer MUST start by sending a protocol |
| header that indicates the protocol version used on the Connection. The protocol header |
| consists of the upper case ASCII letters "AMQP" followed by a protocol id of zero, followed |
| by three unsigned bytes representing the major, minor, and revision of the protocol version |
| (currently <xref name="MAJOR"/>, <xref name="MINOR"/>, <xref name="REVISION"/>). In total |
| this is an 8-octet sequence: |
| </p> |
| |
| <picture><![CDATA[ |
| 4 OCTETS 1 OCTET 1 OCTET 1 OCTET 1 OCTET |
| +----------+---------+---------+---------+----------+ |
| | "AMQP" | %d0 | major | minor | revision | |
| +----------+---------+---------+---------+----------+ |
| ]]> |
| </picture> |
| |
| <p> |
| Any data appearing beyond the protocol header MUST match the version indicated by the |
| protocol header. If the incoming and outgoing protocol headers do not match, both peers MUST |
| close their outgoing stream and SHOULD read the incoming stream until it is terminated. |
| </p> |
| |
| <p> |
| The AMQP peer which acted in the role of the TCP client (i.e. the peer that opened the |
| Connection) MUST immediately send its outgoing protocol header on establishment of the TCP |
| Session. The AMQP peer which acted in the role of the TCP server MAY elect to wait until |
| receiving the incoming protocol header before sending its own outgoing protocol header. |
| </p> |
| |
| <p> |
| Two AMQP peers agree on a protocol version as follows (where the words "client" and |
| "server" refer to the roles being played by the peers at the TCP Connection level): |
| </p> |
| |
| <ul> |
| <li> |
| <p> |
| When the client opens a new socket Connection to a server, it MUST send a protocol |
| header with the client's preferred protocol version. |
| </p> |
| </li> |
| |
| <li> |
| <p> |
| If the requested protocol version is supported, the server MUST send its own protocol |
| header with the requested version to the socket, and then proceed according to the |
| protocol definition. |
| </p> |
| </li> |
| |
| <li> |
| <p> |
| If the requested protocol version is <b>not</b> supported, the server MUST send a |
| protocol header with a <b>supported</b> protocol version and then close the socket. |
| </p> |
| </li> |
| |
| <li> |
| <p> |
| When choosing a protocol version to respond with, the server SHOULD choose the highest |
| supported version that is less than or equal to the requested version. If no such |
| version exists, the server SHOULD respond with the highest supported version. |
| </p> |
| </li> |
| |
| <li> |
| <p> |
| If the server can't parse the protocol header, the server MUST send a valid protocol |
| header with a supported protocol version and then close the socket. |
| </p> |
| </li> |
| </ul> |
| |
| <p> |
| Based on this behavior a client can discover which protocol versions a server supports by |
| attempting to connect with its highest supported version and reconnecting with a version |
| less than or equal to the version received back from the server. |
| </p> |
| |
| <picture title="Version Negotiation Examples"><![CDATA[ |
| TCP Client TCP Server |
| ====================================================== |
| AMQP%d0.1.0.0 -------------> |
| <------------- AMQP%d0.1.0.0 (1) |
| ... *proceed* |
| |
| AMQP%d0.1.1.0 -------------> |
| <------------- AMQP%d0.1.0.0 (2) |
| *TCP CLOSE* |
| |
| HTTP -------------> |
| <------------- AMQP%d0.1.0.0 (3) |
| *TCP CLOSE* |
| ------------------------------------------------------ |
| (1) Server accepts Connection for: AMQP, protocol=0, |
| major=1, minor=0, revision=0 |
| |
| (2) Server rejects Connection for: AMQP, protocol=0, |
| major=1, minor=1, revision=0, Server responds |
| that it supports: AMQP, protocol=0, major=1, |
| minor=0, revision=0 |
| |
| (3) Server rejects Connection for: HTTP. Server |
| responds it supports: AMQP, protocol=0, major=1, |
| minor=0, revision=0 |
| ]]> |
| </picture> |
| |
| <p> |
| Please note that the above examples use the literal notation defined in RFC 2234 for non |
| alphanumeric values. |
| </p> |
| |
| <p> |
| The protocol id is not a part of the protocol version and thus the rule above regarding |
| the highest supported version does not apply. A client might request use of a protocol id |
| that is unacceptable to a server - for example, it might request a raw AMQP connection |
| when the server is configured to require a TLS or SASL security layer (See <xref |
| type="section" name="security-layers"/>). In this case, the server MUST send a protocol |
| header with an <b>acceptable</b> protocol id (and version) and then close the socket. It MAY |
| choose any protocol id. |
| </p> |
| |
| <picture title="Protocol ID Rejection Example"><![CDATA[ |
| TCP Client TCP Server |
| ====================================================== |
| AMQP%d0.1.0.0 -------------> |
| <------------- AMQP%d3.1.0.0 |
| *TCP CLOSE* |
| ------------------------------------------------------ |
| Server rejects Connection for: AMQP, protocol=0, |
| major=1, minor=0, revision=0, Server responds |
| that it requires: SASL security layer, protocol=3, |
| major=1, minor=0, revision=0 |
| ]]> |
| </picture> |
| </doc> |
| </section> |
| |
| <section name="framing" label="frame layout and encoding"> |
| <doc> |
| <p> |
| Frames are divided into three distinct areas: a fixed width frame header, a variable width |
| extended header, and a variable width frame body. |
| </p> |
| |
| <picture><![CDATA[ |
| required optional optional |
| +--------------+-----------------+------------+ |
| | frame header | extended header | frame body | |
| +--------------+-----------------+------------+ |
| 8 bytes *variable* *variable* |
| ]]> |
| </picture> |
| |
| <dl> |
| <dt>frame header</dt> |
| <dd><p>The frame header is a fixed size (8 byte) structure that precedes each frame. The |
| frame header includes mandatory information required to parse the rest of the frame |
| including size and type information.</p></dd> |
| |
| <dt>extended header</dt> |
| <dd><p>The extended header is a variable width area preceding the frame body. This is an |
| extension point defined for future expansion. The treatment of this area depends on the |
| frame type.</p></dd> |
| |
| <dt>frame body</dt> |
| <dd><p>The frame body is a variable width sequence of bytes the format of which depends on |
| the frame type.</p></dd> |
| </dl> |
| </doc> |
| |
| <doc title="Frame Layout"> |
| <p> |
| The diagram below shows the details of the general frame layout for all frame types. |
| </p> |
| |
| <picture><![CDATA[ |
| +0 +1 +2 +3 |
| +-----------------------------------+ -. |
| 0 | SIZE | | |
| +-----------------------------------+ |---> Frame Header |
| 4 | DOFF | TYPE | <TYPE-SPECIFIC> | | (8 bytes) |
| +-----------------------------------+ -' |
| +-----------------------------------+ -. |
| 8 | ... | | |
| . . |---> Extended Header |
| . <TYPE-SPECIFIC> . | (DOFF * 4 - 8) bytes |
| | ... | | |
| +-----------------------------------+ -' |
| +-----------------------------------+ -. |
| 4*DOFF | | | |
| . . | |
| . . | |
| . . | |
| . <TYPE-SPECIFIC> . |---> Frame Body |
| . . | (SIZE - DOFF * 4) bytes |
| . . | |
| . . | |
| . ________| | |
| | ... | | |
| +--------------------------+ -' |
| ]]> |
| </picture> |
| |
| <dl> |
| <dt>SIZE</dt> |
| <dd><p>Bytes 0-3 of the frame header contain the frame size. This is an unsigned 32-bit |
| integer that MUST contain the total frame size of the frame header, extended header, and |
| frame body. The frame is malformed if the size is less than the size of the required |
| frame header (8 bytes).</p></dd> |
| |
| <dt>DOFF</dt> |
| <dd><p>Byte 4 of the frame header is the data offset. This gives the position of the body |
| within the frame. The value of the data offset is unsigned 8-bit integer specifying a |
| count of 4 byte words. Due to the mandatory 8 byte frame header, the frame is malformed |
| if the value is less than 2.</p></dd> |
| |
| <dt>TYPE</dt> |
| <dd><p>Byte 5 of the frame header is a type code. The type code indicates the format and |
| purpose of the frame. The subsequent bytes in the frame header may be interpreted |
| differently depending on the type of the frame. A type code of 0x00 indicates that the |
| frame is an AMQP frame. (A type code of 0x01 indicates that the frame is a SASL frame, |
| see <xref type="section" name="sasl"/>). |
| </p></dd> |
| </dl> |
| </doc> |
| |
| <doc title="AMQP Frames"> |
| <p> |
| Bytes 6 and 7 of an AMQP Frame contain the Channel number (see <xref name="transport"/>). |
| The frame body is defined as a <i>performative</i> followed by an opaque <i>payload</i>. The |
| performative MUST be one of those defined in <xref name="performatives"/> and is encoded as |
| a described type in the AMQP type system. The remaining bytes in the frame body form the |
| payload for that frame. The presence and format of the payload is defined by the semantics |
| of the given performative. |
| </p> |
| |
| <picture><![CDATA[ |
| type: 0x00 - AMQP frame |
| |
| +0 +1 +2 +3 |
| +-----------------------------------+ -. |
| 0 | SIZE | | |
| +-----------------------------------+ |---> Frame Header |
| 4 | DOFF | TYPE | CHANNEL | | (8 bytes) |
| +-----------------------------------+ -' |
| +-----------------------------------+ -. |
| 8 | ... | | |
| . . |---> Extended Header |
| . <IGNORED> . | (DOFF * 4 - 8) bytes |
| | ... | | |
| +-----------------------------------+ -' |
| +-----------------------------------+ -. |
| 4*DOFF | PERFORMATIVE: | | |
| . Open / Begin / Attach . | |
| . Flow / Transfer / Disposition . | |
| . Detach / End / Close . | |
| |-----------------------------------| | |
| . . |---> Frame Body |
| . . | (SIZE - DOFF * 4) bytes |
| . PAYLOAD . | |
| . . | |
| . ________| | |
| | ... | | |
| +--------------------------+ -' |
| ]]> |
| </picture> |
| |
| <p> |
| An AMQP frame with no body may be used to generate artificial traffic as needed to |
| satisfy any negotiated idle time-out interval. See <xref name="doc-idle-time-out"/>. |
| </p> |
| </doc> |
| </section> |
| |
| <!-- == Section: connections ================================================================= --> |
| |
| <section name="connections" label="connection life-cycle"> |
| <doc> |
| <p> |
| AMQP Connections are divided into a number of unidirectional Channels. A Connection Endpoint |
| contains two kinds of Channel endpoints: incoming and outgoing. A Connection Endpoint maps |
| incoming Frames other than <xref name="open"/> and <xref name="close"/> to an incoming |
| Channel endpoint based on the incoming Channel number, as well as relaying Frames produced |
| by outgoing Channel endpoints, marking them with the associated outgoing Channel number |
| before sending them. |
| </p> |
| |
| <p> |
| This requires Connection endpoints to contain two mappings. One from incoming Channel number |
| to incoming Channel endpoint, and one from outgoing Channel endpoint, to outgoing Channel |
| number. |
| </p> |
| |
| <picture><![CDATA[ |
| +-------OCHE X: 1 |
| | |
| +-------OCHE Y: 7 |
| | |
| <=== Frame[CH=1], Frame[CH=7] <===+ |
| |
| ===> Frame[CH=0], Frame[CH=1] ===>+ |
| | |
| +------>0: ICHE A |
| | |
| +------>1: ICHE B |
| |
| OCHE: Outgoing Channel Endpoint |
| ICHE: Incoming Channel Endpoint |
| ]]> |
| </picture> |
| |
| <p> |
| Channels are unidirectional, and thus at each Connection endpoint the incoming and outgoing |
| Channels are completely distinct. Channel numbers are scoped relative to direction, thus |
| there is no causal relation between incoming and outgoing Channels that happen to be |
| identified by the "same" number. This means that if a bidirectional endpoint is constructed |
| from an incoming Channel endpoint and an outgoing Channel endpoint, the Channel number used |
| for incoming Frames is not necessarily the same as the Channel number used for outgoing |
| Frames. |
| </p> |
| |
| <picture><![CDATA[ |
| +-------BIDI/O: 7 |
| | |
| <=== Frame[CH=1], Frame[CH=7] <===+ |
| |
| ===> Frame[CH=0], Frame[CH=1] ===>+ |
| | |
| +------>1: BIDI/I |
| |
| BIDI/I: Incoming half of a single bidirectional endpoint |
| BIDI/O: Outgoing half of a single bidirectional endpoint |
| ]]> |
| </picture> |
| |
| <p> |
| Although not strictly directed at the Connection endpoint, the <xref name="begin"/> and |
| <xref name="end"/> Frames may be useful for the Connection endpoint to intercept as these |
| Frames are how Sessions mark the beginning and ending of communication on a given Channel |
| (see <xref name="sessions"/>). |
| </p> |
| </doc> |
| |
| <doc title="Opening a Connection"> |
| <p> |
| Each AMQP Connection begins with an exchange of capabilities and limitations, including the |
| maximum frame size. Prior to any explicit negotiation, the maximum frame size is |
| <xref name="MIN-MAX-FRAME-SIZE"/> and the maximum channel number is 0. After establishing |
| or accepting a TCP Connection and sending the protocol header, each peer must send an |
| <xref type="type" name="open"/> frame before sending any other Frames. The |
| <xref type="type" name="open"/> frame describes the capabilities and limits of that peer. |
| The <xref type="type" name="open"/> frame can only be sent on channel 0. After sending the |
| <xref type="type" name="open"/> frame each peer must read its partner's |
| <xref type="type" name="open"/> frame and must operate within mutually acceptable |
| limitations from this point forward. |
| </p> |
| |
| <picture><![CDATA[ |
| TCP Client TCP Server |
| ================================== |
| TCP-CONNECT TCP-ACCEPT |
| PROTO-HDR PROTO-HDR |
| OPEN ---+ +--- OPEN |
| \ / |
| wait x wait |
| / \ |
| proceed <--+ +--> proceed |
| |
| ... |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Pipelined Open"> |
| <p> |
| For applications that use many short-lived Connections, it may be desirable to pipeline the |
| Connection negotiation process. A peer may do this by starting to send subsequent frames |
| before receiving the partner's Connection header or <xref type="type" name="open"/> frame. |
| This is permitted so long as the pipelined frames are known a priori to conform to the |
| capabilities and limitations of its partner. For example, this may be accomplished by |
| keeping the use of the Connection within the capabilities and limits expected of all AMQP |
| implementations as defined by the specification of the <xref type="type" name="open"/> |
| frame. |
| </p> |
| |
| <picture><![CDATA[ |
| TCP Client TCP Server |
| ============================================= |
| TCP-CONNECT TCP-ACCEPT |
| PROTO-HDR PROTO-HDR |
| OPEN ---+ +--- OPEN |
| \ / |
| pipelined frame x pipelined frame |
| / \ |
| proceed <--+ +--> proceed |
| |
| ... |
| --------------------------------------------- |
| |
| ]]> |
| </picture> |
| <p> |
| The use of pipelined frames by a peer cannot be distinguished by the peer's partner from |
| non-pipelined use so long as the pipelined frames conform to the partner's capabilities and |
| limitations. |
| </p> |
| </doc> |
| |
| <doc title="Closing a Connection"> |
| <p> |
| Prior to closing a Connection, each peer MUST write a <xref type="type" name="close"/> frame |
| with a code indicating the reason for closing. This frame MUST be the last thing ever |
| written onto a Connection. After writing this frame the peer SHOULD continue to read from |
| the Connection until it receives the partner's <xref type="type" name="close"/> frame (in |
| order to guard against erroneously or maliciously implemented partners, a peer SHOULD |
| implement a timeout to give its partner a reasonable time to receive and process the close |
| before giving up and simply closing the underlying transport mechanism). A <xref type="type" |
| name="close"/> frame may be received on any channel up to the maximum channel number |
| negotiated in open. However, implementations SHOULD send it on channel 0, and MUST send it |
| on channel 0 if pipelined in a single batch with the corresponding <xref name="open"/>. |
| </p> |
| |
| <picture><![CDATA[ |
| TCP Client TCP Server |
| ============================= |
| ... |
| |
| CLOSE -------> |
| +-- CLOSE |
| / TCP-CLOSE |
| TCP-CLOSE <--+ |
| ]]> |
| </picture> |
| |
| <p> |
| Implementations SHOULD NOT expect to be able to reuse open TCP sockets after <xref |
| type="type" name="close"/> performatives have been exchanged. There is no requirement for an |
| implementation to read from a socket after a <xref type="type" name="close"/> performative |
| has been received. |
| </p> |
| |
| </doc> |
| |
| <doc title="Simultaneous Close"> |
| <p> |
| Normally one peer will initiate the Connection close, and the partner will send its close in |
| response. However, because both endpoints may simultaneously choose to close the Connection |
| for independent reasons, it is possible for a simultaneous close to occur. In this case, the |
| only potentially observable difference from the perspective of each endpoint is the code |
| indicating the reason for the close. |
| </p> |
| |
| <picture><![CDATA[ |
| TCP Client TCP Server |
| ================================ |
| ... |
| |
| CLOSE ---+ +--- CLOSE |
| \ / |
| x |
| / \ |
| TCP-CLOSE <--+ +--> TCP-CLOSE |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc name="doc-idle-time-out" title="Idle Time-out of a Connection"> |
| <p> |
| Connections are subject to an idle time-out threshold. The time-out is triggered by a local |
| peer when no frames are received after a threshold value is exceeded. The idle time-out is |
| measured in milliseconds, and starts from the time the last frame is received. If the |
| threshold is exceeded, then a peer should try to gracefully close the connection using a |
| <xref type="type" name="close"/> frame with an error explaining why. If the remote peer does |
| not respond gracefully within a threshold to this, then the peer may close the TCP socket. |
| </p> |
| |
| <p> |
| Each peer has its own (independent) idle time-out. At Connection open each peer communicates |
| the maximum period between activity (frames) on the connection that it desires from its |
| partner. The <xref type="type" name="open"/> frame carries the idle-time-out field for this |
| purpose. To avoid spurious time-outs, the value in idle-time-out should be half the peer's |
| actual timeout threshold. |
| </p> |
| |
| <p> |
| If a peer can not, for any reason support a proposed idle time-out, then it should close |
| the connection using a <xref type="type" name="close"/> frame with an error explaining why. |
| There is no requirement for peers to support arbitrarily short or long idle time-outs. |
| </p> |
| |
| <p> |
| The use of idle time-outs is any addition to any network protocol level control. |
| Implementations should make use of TCP keep-alive wherever possible in order to be good |
| citizens. |
| </p> |
| |
| <p> |
| If a peer needs to satisfy the need to send traffic to prevent idle time-out, and has |
| nothing to send, it may send an empty frame, i.e. a frame consisting solely of a frame |
| header, with no frame body. This frame's channel can be any valid channel up to channel-max, |
| but is otherwise to be ignored. Implementations SHOULD use channel 0 for empty frames, and |
| MUST use channel 0 if channel-max has not yet been negotiated (i.e. before an |
| <xref name="open"/> frame has been received). Apart from this use, empty frames have no |
| meaning. |
| </p> |
| |
| <p> |
| Empty frames can only be sent after the <xref type="type" name="open"/> frame is sent. |
| As they are a frame, they should not be sent after the <xref type="type" name="close"/> |
| frame has been sent. |
| </p> |
| |
| <p> |
| As an alternative to using an empty frame to prevent an idle time-out, if a connection |
| is in a permissible state, an implementation MAY choose to send a flow frame for a valid |
| session. |
| </p> |
| |
| <p> |
| If during operation a peer exceeds the remote peer's idle time-out's threshold, e.g. |
| because it is heavily loaded, it SHOULD gracefully close the connection by using a |
| <xref type="type" name="close"/> frame with an error explaining why. |
| </p> |
| </doc> |
| |
| <doc title="Connection States"> |
| <dl> |
| <dt>START</dt> |
| <dd><p>In this state a Connection exists, but nothing has been sent or received. This is the |
| state an implementation would be in immediately after performing a socket connect or |
| socket accept.</p></dd> |
| |
| <dt>HDR_RCVD</dt> |
| <dd><p>In this state the Connection header has been received from our peer, but we have not |
| yet sent anything.</p></dd> |
| |
| <dt>HDR_SENT</dt> |
| <dd><p>In this state the Connection header has been sent to our peer, but we have not yet |
| received anything.</p></dd> |
| |
| <dt>OPEN_PIPE</dt> |
| <dd><p>In this state we have sent both the Connection header and the <xref type="type" |
| name="open"/> frame, but we have not yet received anything. |
| </p></dd> |
| |
| <dt>OC_PIPE</dt> |
| <dd><p>In this state we have sent the Connection header, the <xref type="type" name="open"/> |
| frame, any pipelined Connection traffic, and the <xref type="type" name="close"/> frame, |
| but we have not yet received anything.</p></dd> |
| |
| <dt>OPEN_RCVD</dt> |
| <dd><p>In this state we have sent and received the Connection header, and received an |
| <xref type="type" name="open"/> frame from our peer, but have not yet sent an |
| <xref type="type" name="open"/> frame.</p></dd> |
| |
| <dt>OPEN_SENT</dt> |
| <dd><p>In this state we have sent and received the Connection header, and sent an |
| <xref type="type" name="open"/> frame to our peer, but have not yet received an |
| <xref type="type" name="open"/> frame.</p></dd> |
| |
| <dt>CLOSE_PIPE</dt> |
| <dd><p>In this state we have send and received the Connection header, sent an |
| <xref type="type" name="open"/> frame, any pipelined Connection traffic, and the |
| <xref type="type" name="close"/> frame, but we have not yet received an |
| <xref type="type" name="open"/> frame.</p></dd> |
| |
| <dt>OPENED</dt> |
| <dd><p>In this state the Connection header and the <xref type="type" name="open"/> frame |
| have both been sent and received.</p></dd> |
| |
| <dt>CLOSE_RCVD</dt> |
| <dd><p>In this state we have received a <xref type="type" name="close"/> frame indicating |
| that our partner has initiated a close. This means we will never have to read anything |
| more from this Connection, however we can continue to write frames onto the Connection. |
| If desired, an implementation could do a TCP half-close at this point to shutdown the |
| read side of the Connection.</p></dd> |
| |
| <dt>CLOSE_SENT</dt> |
| <dd><p>In this state we have sent a <xref type="type" name="close"/> frame to our partner. |
| It is illegal to write anything more onto the Connection, however there may still be |
| incoming frames. If desired, an implementation could do a TCP half-close at this point |
| to shutdown the write side of the Connection.</p></dd> |
| |
| <dt>DISCARDING</dt> |
| <dd><p>The DISCARDING state is a variant of the CLOSE_SENT state where the |
| <xref name="close"/> is triggered by an error. In this case any incoming frames on |
| the connection MUST be silently discarded until the peer's <xref name="close"/> frame |
| is received.</p></dd> |
| |
| <dt>END</dt> |
| <dd><p>In this state it is illegal for either endpoint to write anything more onto the |
| Connection. The Connection may be safely closed and discarded.</p></dd> |
| </dl> |
| </doc> |
| |
| <doc title="Connection State Diagram"> |
| <p> |
| The graph below depicts a complete state diagram for each endpoint. The boxes represent |
| states, and the arrows represent state transitions. Each arrow is labeled with the action |
| that triggers that particular transition. |
| </p> |
| |
| <picture><![CDATA[ |
| R:HDR @=======@ S:HDR R:HDR[!=S:HDR] |
| +--------| START |-----+ +--------------------------------+ |
| | @=======@ | | | |
| \|/ \|/ | | |
| @==========@ @==========@ S:OPEN | |
| +----| HDR_RCVD | | HDR_SENT |------+ | |
| | @==========@ @==========@ | R:HDR[!=S:HDR] | |
| | S:HDR | | R:HDR | +-----------------+ |
| | +--------+ +------+ | | | |
| | \|/ \|/ \|/ | | |
| | @==========@ +-----------+ S:CLOSE | |
| | | HDR_EXCH | | OPEN_PIPE |----+ | |
| | @==========@ +-----------+ | | |
| | R:OPEN | | S:OPEN | R:HDR | | |
| | +--------+ +------+ +-------+ | | |
| | \|/ \|/ \|/ \|/ | |
| | @===========@ @===========@ S:CLOSE +---------+ | |
| | | OPEN_RCVD | | OPEN_SENT |-----+ | OC_PIPE |--+ |
| | @===========@ @===========@ | +---------+ | |
| | S:OPEN | | R:OPEN \|/ | R:HDR | |
| | | @========@ | +------------+ | | |
| | +------>| OPENED |<----+ | CLOSE_PIPE |<--+ | |
| | @========@ +------------+ | |
| | R:CLOSE | | S:CLOSE | R:OPEN | |
| | +---------+ +-------+ | | |
| | \|/ \|/ | | |
| | @============@ @=============@ | | |
| | | CLOSE_RCVD | | CLOSE_SENT* |<----+ | |
| | @============@ @=============@ | |
| | S:CLOSE | | R:CLOSE | |
| | | @=====@ | | |
| | +-------->| END |<-----+ | |
| | @=====@ | |
| | /|\ | |
| | S:HDR[!=R:HDR] | R:HDR[!=S:HDR] | |
| +----------------------+-----------------------------------------------+ |
| |
| R:<CTRL> = Received <CTRL> |
| S:<CTRL> = Sent <CTRL> |
| * Also could be DISCARDING if an error condition |
| triggered the CLOSE |
| ]]> |
| </picture> |
| |
| <picture><![CDATA[ |
| State Legal Sends Legal Receives Legal Connection Actions |
| ======================================================================= |
| START HDR HDR |
| HDR_RCVD HDR OPEN |
| HDR_SENT OPEN HDR |
| HDR_EXCH OPEN OPEN |
| OPEN_RCVD OPEN * |
| OPEN_SENT ** OPEN |
| OPEN_PIPE ** HDR |
| CLOSE_PIPE - OPEN TCP Close for Write |
| OC_PIPE - HDR TCP Close for Write |
| OPENED * * |
| CLOSE_RCVD * - TCP Close for Read |
| CLOSE_SENT - * TCP Close for Write |
| DISCARDING - * TCP Close for Write |
| END - - TCP Close |
| |
| * = any frames |
| - = no frames |
| ** = any frame known a priori to conform to the |
| peer's capabilities and limitations |
| ]]> |
| </picture> |
| </doc> |
| |
| </section> |
| |
| <!-- == Section: sessions ==================================================================== --> |
| |
| <section name="sessions" label="context for active link communication"> |
| <doc> |
| <p> |
| A Session is a bidirectional sequential conversation between two containers that provides a |
| grouping for related links. Sessions serve as the context for link communication. Any number |
| of links of any directionality can be <i>attached</i> to a given Session. However, a link |
| may be attached to at most one Session at a time. |
| </p> |
| |
| <picture> |
| <![CDATA[ |
| Link A-------+ +------>Link A |
| | | |
| \|/ (attached) | |
| Link B<--- Session <--------------> Session <---Link B |
| |
| |
| Link C------>* (detached) *------>Link C |
| ]]> |
| </picture> |
| |
| <p> |
| Messages transferred on a link are sequentially identified within the Session. A session may |
| be viewed as multiplexing link traffic, much like a connection multiplexes session traffic. |
| However, unlike the sessions on a connection, links on a session are not entirely |
| independent since they share a common delivery sequence scoped to the session. This common |
| sequence allows endpoints to efficiently refer to sets of deliveries regardless of the |
| originating link. This is of particular benefit when a single application is receiving |
| messages along a large number of different links. In this case the session |
| provides <i>aggregation</i> of otherwise independent links into a single stream that can be |
| efficiently acknowledged by the receiving application. |
| </p> |
| |
| </doc> |
| |
| <doc title="Establishing a Session"> |
| <p> |
| Sessions are established by creating a Session Endpoint, assigning it to an unused channel |
| number, and sending a <xref type="type" name="begin"/> announcing the association of the |
| Session Endpoint with the outgoing channel. Upon receiving the <xref type="type" |
| name="begin"/> the partner will check the remote-channel field and find it empty. This |
| indicates that the begin is referring to remotely initiated Session. The partner will |
| therefore allocate an unused outgoing channel for the remotely initiated Session and |
| indicate this by sending its own <xref type="type" name="begin"/> setting the |
| remote-channel field to the incoming channel of the remotely initiated Session. |
| </p> |
| |
| <p> |
| To make it easier to monitor AMQP sessions, it is recommended that implementations always |
| assign the lowest available unused channel number. |
| </p> |
| |
| <p> |
| The remote-channel field of a <xref type="type" name="begin"/> frame MUST be empty for a |
| locally initiated Session, and MUST be set when announcing the endpoint created as a result |
| of a remotely initiated Session. |
| </p> |
| |
| <picture><![CDATA[ |
| Endpoint Endpoint |
| ===================================================================== |
| [CH3] BEGIN(name=..., ---------> |
| remote-channel=null) |
| +-- [CH7] BEGIN(name=..., |
| / remote-channel=3) |
| / |
| <---+ |
| |
| ... |
| |
| --------------------------------------------------------------------- |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Ending a Session"> |
| <p> |
| Sessions end automatically when the Connection is closed or interrupted. Sessions are |
| explicitly ended when either endpoint chooses to end the Session. When a Session is |
| explicitly ended, an <xref type="type" name="end"/> frame is sent to announce the |
| disassociation of the endpoint from its outgoing channel, and to carry error information |
| when relevant. |
| </p> |
| |
| <picture><![CDATA[ |
| Endpoint A Endpoint B |
| ==================================================================== |
| |
| ... |
| |
| [CH3] END(error=...) ---------> (1) |
| +-- [CH7] END(error=...) |
| / |
| / |
| (2) <---+ |
| |
| ... |
| |
| -------------------------------------------------------------------- |
| |
| (1) At this point the session endpoint is disassociated from |
| the outgoing channel on A, and the incoming channel on B. |
| |
| (2) At this point the session endpoint is disassociated from |
| the outgoing channel on B, and the incoming channel on A. |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Simultaneous End"> |
| <p> |
| Due to the potentially asynchronous nature of Sessions, it is possible that both peers may |
| simultaneously decide to end a Session. If this should happen, it will appear to each peer |
| as though their partner's spontaneously initiated <xref type="type" name="end"/> frame is |
| actually an answer to the peers initial <xref type="type" name="end"/> frame. |
| </p> |
| |
| <picture><![CDATA[ |
| Endpoint A Endpoint B |
| ================================================================= |
| |
| ... |
| |
| [CH3] END(error=...) --+ +-- [CH7] END(error=...) |
| (1) \ / (2) |
| x |
| / \ |
| (3) <-+ +-> (4) |
| |
| ... |
| |
| ----------------------------------------------------------------- |
| |
| (1) At this point no more frames may be sent by A. |
| |
| (2) At this point no more frames may be sent by B. |
| |
| (3) At this point Endpoint A is fully ended. |
| |
| (4) At this point Endpoint B is fully ended. |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Session Errors" > |
| <p> |
| When a Session is unable to process input, it MUST indicate this by issuing an END with an |
| appropriate <xref name="error"/> indicating the cause of the problem. It MUST then proceed |
| to discard all incoming frames from the remote endpoint until hearing the remote endpoint's |
| corresponding <xref name="end"/> frame. |
| </p> |
| |
| <picture><![CDATA[ |
| Endpoint Endpoint |
| ================================================ |
| FRAME 1 ----------> |
| FRAME 2 ----------> |
| FRAME 3 ---+ +--- END(error=...) |
| \ / |
| x |
| / \ |
| <--+ +--> *discarded* |
| END ----------> |
| ... |
| ================================================ |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Session States"> |
| <dl> |
| <dt>UNMAPPED</dt> |
| <dd><p>In the UNMAPPED state, the Session endpoint is not mapped to any incoming or outgoing |
| channels on the Connection endpoint. In this state an endpoint cannot send or receive |
| frames.</p></dd> |
| |
| <dt>BEGIN_SENT</dt> |
| <dd><p>In the BEGIN_SENT state, the Session endpoint is assigned an outgoing channel number, |
| but there is no entry in the incoming channel map. In this state the endpoint may send |
| frames but cannot receive them.</p></dd> |
| |
| <dt>BEGIN_RCVD</dt> |
| <dd><p>In the BEGIN_RCVD state, the Session endpoint has an entry in the incoming channel |
| map, but has not yet been assigned an outgoing channel number. The endpoint may receive |
| frames, but cannot send them.</p></dd> |
| |
| <dt>MAPPED</dt> |
| <dd><p>In the MAPPED state, the Session endpoint has both an outgoing channel number and an |
| entry in the incoming channel map. The endpoint may both send and receive |
| frames.</p></dd> |
| |
| <dt>END_SENT</dt> |
| <dd><p>In the END_SENT state, the Session endpoint has an entry in the incoming channel map, |
| but is no longer assigned an outgoing channel number. The endpoint may receive frames, |
| but cannot send them.</p></dd> |
| |
| <dt>END_RCVD</dt> |
| <dd><p>In the END_RCVD state, the Session endpoint is assigned an outgoing channel number, |
| but there is no entry in the incoming channel map. The endpoint may send frames, but |
| cannot receive them.</p></dd> |
| |
| <dt>DISCARDING</dt> |
| <dd><p>The DISCARDING state is a variant of the END_SENT state where the <xref name="end"/> |
| is triggered by an error. In this case any incoming frames on the session MUST be |
| silently discarded until the peer's <xref name="end"/> frame is received.</p></dd> |
| </dl> |
| |
| <picture title="State Transitions"><![CDATA[ |
| UNMAPPED<-------------------+ |
| | | |
| +-------+-------+ | |
| S:BEGIN | | R:BEGIN | |
| | | | |
| \|/ \|/ | |
| BEGIN_SENT BEGIN_RCVD | |
| | | | |
| | | | |
| R:BEGIN | | S:BEGIN | |
| +-------+-------+ | |
| | | |
| \|/ | |
| MAPPED | |
| | | |
| +-------------+-------------+ | |
| S:END(error) | S:END | | R:END | |
| | | | | |
| \|/ \|/ \|/ | |
| DISCARDING END_SENT END_RCVD | |
| | | | | |
| | | | | |
| R:END | R:END | | S:END | |
| +-------------+-------------+ | |
| | | |
| | | |
| +------------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| There is no obligation to retain a Session Endpoint when it is in the UNMAPPED state, i.e. |
| the UNMAPPED state is equivalent to a NONEXISTENT state. |
| </p> |
| </doc> |
| |
| <doc name="session-flow-control" title="Session Flow Control"> |
| <p> |
| The Session Endpoint assigns each outgoing <xref name="transfer"/> frame an implicit |
| <i>transfer-id</i> from a session scoped sequence. Each session endpoint maintains the |
| following state to manage incoming and outgoing <xref name="transfer"/> frames: |
| </p> |
| |
| <dl> |
| <dt>next-incoming-id</dt> |
| <dd><p>The <i>next-incoming-id</i> identifies the implicit transfer-id of the next incoming |
| <xref name="transfer"/> frame.</p></dd> |
| |
| <dt>incoming-window</dt> |
| <dd><p>The <i>incoming-window</i> defines the maximum number of incoming |
| <xref name="transfer"/> frames that the endpoint can currently receive. This identifies |
| a current maximum incoming transfer-id that can be computed by subtracting one from the |
| sum of <i>incoming-window</i> and <i>next-incoming-id</i>.</p></dd> |
| |
| <dt>next-outgoing-id</dt> |
| <dd><p>The <i>next-outgoing-id</i> is used to assign a unique transfer-id to all |
| outgoing transfer frames on a given session. The <i>next-outgoing-id</i> may be |
| initialized to an arbitrary value and is incremented after each successive |
| <xref name="transfer"/> according to RFC-1982 serial number arithmetic.</p></dd> |
| |
| <dt>outgoing-window</dt> |
| <dd><p>The <i>outgoing-window</i> defines the maximum number of outgoing |
| <xref name="transfer"/> frames that the endpoint can currently send. This identifies a |
| current maximum outgoing transfer-id that can be computed by subtracting one from the |
| sum of <i>outgoing-window</i> and <i>next-outgoing-id</i>.</p></dd> |
| |
| <dt>remote-incoming-window</dt> |
| <dd><p>The <i>remote-incoming-window</i> reflects the maximum number of outgoing transfers |
| that can be sent without exceeding the remote endpoint's incoming-window. This value MUST |
| be decremented after every <xref name="transfer"/> frame is sent, and recomputed when |
| informed of the remote session endpoint state.</p></dd> |
| |
| <dt>remote-outgoing-window</dt> |
| <dd><p>The <i>remote-outgoing-window</i> reflects the maximum number of incoming transfers |
| that may arrive without exceeding the remote endpoint's outgoing-window. This value MUST |
| be decremented after every incoming <xref name="transfer"/> frame is received, and |
| recomputed when informed fo the remote session endpoint state. When this window shrinks, |
| it is an indication of outstanding transfers. Settling outstanding transfers may cause the |
| window to grow.</p></dd> |
| </dl> |
| |
| <p> |
| Once initialized, this state is updated by various events that occur in the lifespan of a |
| session and its associated links: |
| </p> |
| |
| <dl> |
| <dt>sending a transfer</dt> |
| <dd><p>Upon sending a transfer, the sending endpoint will increment its next-outgoing-id, |
| decrement its remote-incoming-window, and may (depending on policy) decrement its |
| outgoing-window.</p></dd> |
| |
| <dt>receiving a transfer</dt> |
| <dd><p>Upon receiving a transfer, the receiving endpoint will increment the next-incoming-id |
| to match the implicit transfer-id of the incoming transfer plus one, as well as |
| decrementing the remote-outgoing-window, and may (depending on policy) decrement its |
| incoming-window.</p></dd> |
| |
| <dt>receiving a flow</dt> |
| <dd><p>When the endpoint receives a <xref name="flow"/> frame from its peer, it MUST update |
| the <i>next-incoming-id</i> directly from the <i>next-outgoing-id</i> of the frame, as |
| well as copy the <i>remote-outgoing-window</i> directly from the <i>outgoing-window</i> |
| of the frame.</p> |
| |
| <p> |
| The <i>remote-incoming-window</i> is computed as follows: |
| </p> |
| |
| <p> |
| <i>next-incoming-id<sub>flow</sub></i> + <i>incoming-window<sub>flow</sub></i> |
| - <i>next-outgoing-id<sub>endpoint</sub></i> |
| </p> |
| |
| <p> |
| If the <i>next-incoming-id</i> field of the <xref name="flow"/> frame is not set, |
| then <i>remote-incoming-window</i> is computed as follows: |
| </p> |
| |
| <p> |
| <i>initial-outgoing-id<sub>endpoint</sub></i> + <i>incoming-window<sub>flow</sub></i> |
| - <i>next-outgoing-id<sub>endpoint</sub></i> |
| </p> |
| </dd> |
| </dl> |
| </doc> |
| </section> |
| |
| <!-- == Section: links ======================================================================= --> |
| |
| <section name="links" label="link endpoints and the link protocol"> |
| <doc> |
| <p> |
| A Link provides a unidirectional transport for Messages between a Source and a Target. The |
| primary responsibility of a Source or Target (a Terminus) is to maintain a record of the |
| status of each active delivery attempt until such a time as it is safe to forget. These are |
| referred to as <term>unsettled</term> deliveries. When a Terminus forgets the state |
| associated with a delivery-tag, it is considered <term>settled</term>. Each delivery attempt |
| is assigned a unique <term>delivery-tag</term> at the Source. The status of an active |
| delivery attempt is known as the <term>Delivery State</term> of the delivery. |
| </p> |
| |
| <p> |
| Link Endpoints interface between a Terminus and a Session Endpoint, and maintain additional |
| state used for active communication between the local and remote endpoints. Link Endpoints |
| therefore come in two flavors: <term>Senders</term> and <term>Receivers</term>. When the |
| sending application submits a Message to the Sender for transport, it also supplies the |
| delivery-tag used by the Source to track the Delivery State. The Link Endpoint assigns each |
| Message a unique <term>delivery-id</term> from a Session scoped sequence. These delivery-ids |
| are used to efficiently reference subsets of the outstanding deliveries on a Session. |
| </p> |
| |
| <p> |
| Termini may exist beyond their associated Link Endpoints, so it is possible for a Session to |
| terminate and the Termini to remain. A Link is said to be <term>suspended</term> if the |
| Termini exist, but have no associated Link Endpoints. The process of associating new Link |
| Endpoints with existing Termini and re-establishing communication is referred to |
| as <term>resuming</term> a Link. |
| </p> |
| |
| <p> |
| The original Link Endpoint state is not necessary for resumption of a Link. Only the |
| unsettled Delivery State maintained at the Termini is necessary for link resume, and this |
| need not be stored directly. The form of delivery-tags is intentionally left open-ended so |
| that they and their related Delivery State can, if desired, be (re)constructed from |
| application state, thereby minimizing or eliminating the need to retain additional |
| protocol-specific state in order to resume a Link. |
| </p> |
| </doc> |
| |
| <doc title="Naming a Link"> |
| <p> |
| Links are named so that they may be recovered when communication is interrupted. Link names |
| MUST uniquely identify the link amongst all links of the same direction between the two |
| participating containers. Link names are only used when attaching a Link, so they may be |
| arbitrarily long without a significant penalty. |
| </p> |
| <p> |
| A link's name uniquely identifies the link from the container of the source to the |
| container of the target node, e.g. if the container of the source node is A, and the |
| container of the target node is B, the link may be globally identified by the (ordered) |
| tuple <i>(A,B,<name>)</i>. |
| </p> |
| <p> |
| Consequently, a link may only be active in one connection at a time. If an attempt is made |
| to attach the link subsequently when it is not suspended, then the link can be 'stolen', |
| i.e. the second attach succeeds and the first attach must then be closed with a link error |
| of <xref name="link-error" choice="stolen"/>. This behavior ensures that in the event of a |
| connection failure occurring and being noticed by one party, that re-establishment has the |
| desired effect. |
| </p> |
| </doc> |
| |
| <doc title="Link Handles"> |
| <p> |
| Each Link Endpoint is assigned a numeric handle used by the peer as a shorthand to refer to |
| the Link in all frames that reference the Link (<xref type="type" name="attach"/>, |
| <xref type="type" name="detach"/>, <xref type="type" name="flow"/>, <xref type="type" |
| name="transfer"/>, <xref type="type" name="disposition"/>). This handle is assigned by the |
| initial <xref type="type" name="attach"/> frame and remains in use until the link is |
| detached. The two Endpoints are not required to use the same handle. This means a peer is |
| free to independently chose its handle when a Link Endpoint is associated with the Session. |
| The locally chosen handle is referred to as the <term>output handle</term>. The remotely |
| chosen handle is referred to as the <term>input handle</term>. |
| </p> |
| |
| <p> |
| At an Endpoint, a Link is considered to be <term>attached</term> when the Link Endpoint |
| exists and has both input and output handles assigned at an active Session Endpoint. A Link |
| is considered to be <term>detached</term> when the Link Endpoint exists, but is not assigned |
| either input or output handles. A Link can be considered <term>half attached</term> |
| (or <term>half detached</term>) when only one of the input or output handles is assigned. |
| </p> |
| |
| <picture><![CDATA[ |
| +-------------------+ +-------------------+ |
| | name: Link_1 | | name: Link_1 | |
| | handle: i | | handle: j | |
| |-------------------| |-------------------| |
| | role: receiver | | role: sender | |
| | source: A |<---+ +--->| source: A | |
| | target: B | | | | target: B | |
| +-------------------+ | | +-------------------+ |
| | | |
| | +---------+ | |
| ... <---+--->| Session |<---+---> ... |
| | +---------+ | |
| | | |
| +-------------------+ | | +-------------------+ |
| | name: Link_N | | | | name: Link_N | |
| | handle: k |<---+ +--->| handle: l | |
| |-------------------| |-------------------| |
| | role: sender | | role: receiver | |
| | source: C | | source: C | |
| | target: D | | target: D | |
| +-------------------+ +-------------------+ |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Establishing or Resuming a Link"> |
| <p> |
| Links are established and/or resumed by creating a Link Endpoint associated with a local |
| Terminus, assigning it to an unused handle, and sending an <xref type="type" name="attach"/> |
| Frame. This frame carries the state of the newly created Link Endpoint, including the local |
| and remote termini, one being the source and one being the target depending on the |
| directionality of the Link Endpoint. On receipt of the <xref name="attach"/>, the remote |
| Session Endpoint creates a corresponding Link Endpoint and informs its application of the |
| attaching Link. The application attempts to locate the Terminus previously associated with |
| the Link. This Terminus is associated with the Link Endpoint and may be updated if its |
| properties do not match those sent by the remote Link Endpoint. If no such Terminus exists, |
| the application MAY choose to create one using the properties supplied by the remote Link |
| Endpoint. The Link Endpoint is then mapped to an unused handle, and an <xref type="type" |
| name="attach"/> Frame is issued carrying the state of the newly created endpoint. Note that |
| if the application chooses not to create a Terminus, the Session Endpoint will still create |
| a Link Endpoint and issue an <xref type="type" name="attach"/> indicating that the Link |
| Endpoint has no associated local terminus. In this case, the Session Endpoint MUST |
| immediately detach the newly created Link Endpoint. |
| </p> |
| |
| <picture title="Establishing a Link"><![CDATA[ |
| Peer Partner |
| ================================================================ |
| *create link endpoint* |
| ATTACH(name=N, handle=1, ----------> *create link endpoint* |
| role=sender, +--- ATTACH(name=N, handle=2, |
| source=A, / role=receiver, |
| target=B) / source=A, |
| / target=B) |
| <--+ |
| ... |
| ---------------------------------------------------------------- |
| ]]> |
| </picture> |
| |
| <p> |
| If there is no pre-existing Terminus, and the peer does not wish to create a new one, this |
| is indicated by setting the local terminus (source or target as appropriate) to null. |
| </p> |
| |
| <picture title="Refusing a Link"><![CDATA[ |
| Peer Partner |
| ================================================================ |
| *create link endpoint* |
| ATTACH(name=N, handle=1, ----------> *create link endpoint* (1) |
| role=sender, +--- ATTACH(name=N, handle=2, |
| source=A, / role=receiver, |
| target=B) / source=A, |
| / target=-) |
| (2) <--+ |
| +--- DETACH(handle=2, |
| / closed=True) |
| / |
| / |
| <--+ |
| DETACH(handle=1, -----------> |
| closed=True) |
| ... |
| ---------------------------------------------------------------- |
| (1) The Link Endpoint is created, but no target is created. |
| (2) At this point the link is established, but it is to a |
| nonexistent target. |
| ]]> |
| </picture> |
| |
| <p> |
| If either end of the Link is already associated with a Terminus, the <xref name="attach"/> |
| frame MUST include its unsettled delivery state. |
| </p> |
| |
| <picture title="Resuming a Link"><![CDATA[ |
| Peer Partner |
| ================================================================ |
| *existing source* |
| ATTACH(name=N, handle=1, ----------> *found existing target* |
| role=sender, +--- ATTACH(name=N, handle=2, (1) |
| source=X, / role=receiver, |
| target=Y, / source=X, |
| unsettled=...) / target=Y, |
| (2) <--+ unsettled=...) |
| ... |
| ---------------------------------------------------------------- |
| (1) The target already exists, and its properties |
| match the peer's expectations. |
| (2) At this point the Link is reestablished with source=X, |
| target=Y. |
| ]]> |
| </picture> |
| |
| |
| <p> |
| Note that the expected Terminus properties may not always match the actual Terminus |
| properties reported by the remote endpoint. In this case, the Link is always considered to |
| be between the Source as described by the Sender, and the Target as described by the |
| Receiver. This can happen both when establishing and when resuming a link. |
| </p> |
| |
| <p> |
| When a link is established, an endpoint may not have all the capabilities necessary to |
| create the terminus exactly matching the expectations of the peer. Should this happen, the |
| endpoint MAY adjust the properties in order to succeed in creating the terminus. In this |
| case the endpoint MUST report the actual properties of the terminus as created. |
| </p> |
| |
| <p> |
| When resuming a link, the Source and Target properties may have changed while the link was |
| suspended. When this happens, the Termini properties communicated in the source and target |
| fields of the <xref name="attach"/> frames may be in conflict. In this case, the Sender is |
| considered to hold the authoritative version of the Source properties, the Receiver is |
| considered to hold the authoritative version of the Target properties. As above, the |
| resulting Link is constructed to be between the Source as described by the Sender, and the |
| Target as described by the Receiver. Once the Link is resumed, either peer is free to |
| continue if the updated properties are acceptable, or if not, <xref type="type" |
| name="detach"/>. |
| </p> |
| |
| <p> |
| Note that a peer MUST take responsibility for verifying that the remote terminus meets its |
| requirements. The remote peer SHOULD NOT attempt to pre-empt whether the terminus will meet |
| the requirements of its partner. This is equally true both for creating and resuming links. |
| </p> |
| |
| <picture title="Resuming an altered Link"><![CDATA[ |
| Peer Partner |
| ================================================================ |
| *existing source* |
| ATTACH(name=N, handle=1, ----------> *found existing target* |
| role=sender, +--- ATTACH(name=N, handle=2, (1) |
| source=A, / role=receiver, |
| target=B, / source=A, |
| unsettled=...) / target=C, |
| (2) <--+ unsettled=...) |
| ... |
| ---------------------------------------------------------------- |
| (1) The Terminus already exists, but its state |
| does not match the Peer's endpoint. |
| (2) At this point the Link is established with source=A, |
| target=C. |
| ]]> |
| </picture> |
| |
| |
| <p> |
| It is possible to resume a Link even if one of the Termini has lost nearly all its state. |
| All that is required is the Link name and direction. This is referred to as |
| <term>recovering</term> a Link. This is done by creating a new Link Endpoint with an empty |
| source or target for incoming or outgoing Links respectively. The full Link state is then |
| constructed from the authoritative source or target supplied by the other endpoint once the |
| Link is established. If the remote peer has no record of the Link, then no terminus will be |
| located, and local terminus (source or target as appropriate) field in the |
| <xref name="attach"/> frame will be null. |
| </p> |
| |
| <picture title="Recovering a Link"><![CDATA[ |
| Peer Partner |
| ================================================================ |
| *create link endpoint* |
| ATTACH(name=N, handle=1, ----------> *found existing target* |
| role=sender, +--- ATTACH(name=N, handle=2, (1) |
| source=X / role=receiver, |
| target=-) / source=X, |
| (2) <---+ target=Y) |
| ... |
| ---------------------------------------------------------------- |
| (1) The target already exists, and its properties are |
| authoritative. |
| (2) At this point the Link is reestablished with source=X, |
| target=Y. |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Detaching and Reattaching a Link"> |
| <p> |
| A Session Endpoint can choose to unmap its output handle for a Link. In this case, the |
| endpoint MUST send a <xref name="detach"/> frame to inform the remote peer that the handle |
| is no longer attached to the Link Endpoint. Should both endpoints do this, the Link may |
| return to a fully detached state. Note that in this case the Link Endpoints may still |
| indirectly communicate via the Session, as there may be active deliveries on the link |
| referenced via delivery-id. |
| </p> |
| |
| <picture><![CDATA[ |
| Peer Partner |
| ============================================================= |
| *create link endpoint* |
| ATTACH(name=N, handle=1 ----------> *create link endpoint* |
| role=sender, +--- ATTACH(name=N, handle=2, |
| source=A, / role=receiver, |
| target=B) / source=A, |
| / target=B) |
| <--+ |
| ... |
| *use link* <---------> *use link* |
| ... |
| DETACH(handle=1) ----------> *detach input handle* |
| (1) *detach output handle* <---------- DETACH(handle=2) |
| ... |
| ------------------------------------------------------------- |
| (1) At this point both endpoints are detached. |
| ]]> |
| </picture> |
| |
| <p> |
| When the state of a Link Endpoint changes, this is can be communicated by detaching and then |
| reattaching with the updated state on the <xref name="attach"/> frame. This can be used to |
| update the properties of the link endpoints, or to update the properties of the Termini. |
| </p> |
| |
| <picture><![CDATA[ |
| Peer Partner |
| ============================================================= |
| ... |
| DETACH(handle=1) ---+ |
| \ |
| \ |
| \ |
| *modify link endpoint* \ |
| +--> *detach input handle* |
| ATTACH(name=N, handle=1 ---+ +--- DETACH(handle=2) |
| role=sender, \ / |
| source=A', \/ |
| target=B') /\ |
| / \ |
| *detach input handle* <--+ +--> *reattach input handle* |
| *modify link endpoint* |
| +--- ATTACH(name=N, handle=2 |
| / role=receiver, |
| / source=A', |
| / target=B') |
| / |
| (1) *reattach input handle* <--+ |
| ... |
| *use link* <---------> *use link* |
| ... |
| ------------------------------------------------------------- |
| (1) At this point the link is updated and attached. |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Link Errors"> |
| <p> |
| When an error occurs at a Link Endpoint, the endpoint MUST be detached with appropriate |
| error information supplied in the error field of the <xref name="detach"/> frame. The Link |
| Endpoint MUST then be destroyed. Should any input (other than a detach) related to the |
| endpoint either via the input handle or delivery-ids be received, the session MUST be |
| terminated with an <xref name="session-error" choice="errant-link"/> session-error. Since |
| the Link Endpoint has been destroyed, the peer cannot reattach, and MUST resume the link in |
| order to restore communication. In order to disambiguate the resume request from a pipelined |
| re-attach the resuming <xref name="attach"/> performative MUST contain a non-null value for |
| its unsettled field. Receipt of a pipelined <xref name="attach"/> MUST result in the session |
| being terminated with an <xref name="session-error" choice="errant-link"/> session-error. |
| </p> |
| |
| </doc> |
| |
| <doc name="closing-a-link" title="Closing a Link"> |
| <p> |
| A peer closes a Link by sending the <xref type="type" name="detach"/> frame with the handle |
| for the specified Link, and the closed flag set to true. The partner will destroy the |
| corresponding Link endpoint, and reply with its own <xref type="type" name="detach"/> frame |
| with the closed flag set to true. |
| </p> |
| |
| <picture title="Closing a Link"><![CDATA[ |
| Peer Partner |
| ============================================================= |
| *create link endpoint* |
| ATTACH(name=N, handle=1 ----------> *create link endpoint* |
| role=sender, +--- ATTACH(name=N, handle=2, |
| source=A, / role=receiver, |
| target=B) / source=A, |
| / target=B) |
| <--+ |
| ... |
| *use link* <---------> *use link* |
| ... |
| DETACH(handle=1, ----------> *destroy link endpoint* |
| closed=True) |
| (1) *destroy link endpoint* <---------- DETACH(handle=2, |
| closed=True) |
| ------------------------------------------------------------- |
| (1) At this point both endpoints are destroyed. |
| ]]> |
| </picture> |
| |
| <p> |
| Note that one peer may send a closing detach while its partner is sending a non-closing |
| detach. In this case, the partner MUST signal that it has closed the link by reattaching and |
| then sending a closing detach. |
| </p> |
| </doc> |
| |
| <doc name="flow-control" title="Flow Control"> |
| <p> |
| Once attached, a Link is subject to flow control of Message transfers. Link Endpoints |
| maintain the following flow control state. This state defines when it is legal to send |
| transfers on an attached Link, as well as indicating when certain interesting conditions, |
| such as insufficient messages to consume the currently available <i>link-credit</i>, or |
| insufficient <i>link-credit</i> to send available messages: |
| </p> |
| |
| <dl> |
| <dt>delivery-count</dt> |
| <dd><p>The <i>delivery-count</i> is initialized by the Sender when a Link Endpoint is |
| created, and is incremented whenever a Message is sent (at the Sender) or received (at |
| the Receiver). Only the Sender may independently modify this field. The Receiver's |
| value is calculated based on the last known value from the Sender and any subsequent |
| Messages received on the Link.</p></dd> |
| |
| <dt>link-credit</dt> |
| <dd><p>The <i>link-credit</i> variable defines the current maximum legal amount that the |
| <i>delivery-count</i> may be increased. This identifies a <i>delivery-limit</i> that may |
| be computed by adding the <i>link-credit</i> to the <i>delivery-count</i>.</p> |
| |
| <p>Only the Receiver can independently choose a value for this field. The Sender's value |
| MUST always be maintained in such a way as to match the <i>delivery-limit</i> identified |
| by the Receiver. This means that the Sender's link-credit variable MUST be set according |
| to this formula when flow information is given by the receiver:</p> |
| |
| <p> |
| <i>link-credit</i><sub>snd</sub> := <i>delivery-count</i><sub>rcv</sub> + |
| <i>link-credit</i><sub>rcv</sub> - <i>delivery-count</i><sub>snd</sub>. |
| </p> |
| |
| <p> |
| In the event that the receiver does not yet know the <i>delivery-count</i>, i.e. |
| <i>delivery-count</i><sub>rcv</sub> is unspecified, the Sender MUST assume that |
| the <i>delivery-count</i><sub>rcv</sub> is the first |
| <i>delivery-count</i><sub>snd</sub> sent from Sender to Receiver, i.e. the |
| <i>delivery-count</i><sub>snd</sub> specified in the flow state carried by the initial |
| <xref name="attach"/> frame from the Sender to the Receiver. |
| </p> |
| |
| <p> |
| Additionally, whenever the Sender increases <i>delivery-count</i>, it MUST decrease |
| <i>link-credit</i> by the same amount in order to maintain the <i>delivery-limit</i> |
| identified by the Receiver. |
| </p> |
| </dd> |
| |
| <dt>available</dt> |
| <dd><p>The <i>available</i> variable is controlled by the Sender, and indicates to the |
| Receiver, that the Sender could make use of the indicated amount of <i>link-credit</i>. |
| Only the Sender can independently modify this field. The Receiver's value is calculated |
| based on the last known value from the Sender and any subsequent incoming Messages |
| received. The Sender MAY transfer Messages even if the available variable is zero. |
| Should this happen, the Receiver MUST maintain a floor of zero in it's calculation of |
| the value of available.</p></dd> |
| |
| <dt>drain</dt> |
| <dd><p>The drain flag indicates how the Sender should behave when insufficient messages are |
| available to consume the current link-credit. If set, the Sender will (after sending all |
| available messages) advance the delivery-count as much as possible, consuming all |
| link-credit, and send the flow state to the Receiver. Only the Receiver can |
| independently modify this field. The Sender's value is always the last known value |
| indicated by the Receiver.</p></dd> |
| </dl> |
| |
| <p> |
| If the link-credit is less than or equal to zero, i.e. the delivery-count is the same as or |
| greater than the delivery-limit, it is illegal to send more messages. If the link-credit is |
| reduced by the Receiver when transfers are in-flight, the Receiver MAY either handle the |
| excess messages normally or detach the Link with a transfer-limit-exceeded error code. |
| </p> |
| |
| <picture><![CDATA[ |
| +----------+ +----------+ |
| | Sender |---------------transfer------------>| Receiver | |
| +----------+ +----------+ |
| \ / <----------------flow--------------- \ / |
| +------+ +------+ |
| | |
| | |
| | |
| if link-credit <= 0 then pause |
| ]]> |
| </picture> |
| |
| <p> |
| If the Sender's drain flag is set and there are no available messages, the Sender MUST |
| advance its delivery-count until link-credit is zero, and send its updated |
| <xref name="flow"/> state to the Receiver. |
| </p> |
| |
| <p> |
| The delivery-count is an absolute value. While the value itself is conceptually unbounded, |
| it is encoded as a 32-bit integer that wraps around and compares according to RFC-1982 |
| serial number arithmetic. |
| </p> |
| |
| <p> |
| The initial flow state of a Link Endpoint is determined as follows. The <i>link-credit</i> |
| and <i>available</i> variables are initialized to zero. The <i>drain</i> flag is initialized |
| to False. The Sender may choose an arbitrary point to initialize the <i>delivery-count</i>. |
| This value is communicated in the initial <xref name="attach"/> frame. The Receiver |
| initializes its <i>delivery-count</i> upon receiving the Sender's <xref name="attach"/>. |
| </p> |
| |
| <picture><![CDATA[ |
| flow state |
| | |
| | modifies |
| +------------------+ | +------------------+ |
| | Sender | .----------------------. | Receiver | |
| +------------------+ attach, transfer, flow +------------------+ |
| | delivery-count |------------------------------->| delivery-count | |
| | link-credit | | link-credit | |
| | available |<-------------------------------| available | |
| | drain | flow | drain | |
| +------------------+ '-----' +------------------+ |
| | |
| | modifies |
| | |
| flow state |
| ]]> |
| </picture> |
| |
| <p> |
| The flow control semantics defined in this section provide the primitives necessary to |
| implement a wide variety of flow control strategies. Additionally, by manipulating the |
| link-credit and drain flag, a Receiver can provide a variety of different higher level |
| behaviors often useful to applications, including synchronous blocking fetch, synchronous |
| fetch with a timeout, asynchronous notifications, and stopping/pausing. |
| </p> |
| |
| <picture><![CDATA[ |
| +----------+ +----------+ |
| | Receiver |<--------------transfer-------------| Sender | |
| +----------+ +----------+ |
| \ / -----------------flow--------------> \ / |
| +------+ +------+ |
| | |
| | |
| | |
| sync-get: flow(link-credit=1, ...) ----> |
| timed-get: flow(link-credit=1, ...), |
| *wait*, |
| flow(drain=True, ...) ----> |
| async-notify: flow(link-credit=delta, ...) ----> |
| stop: flow(link-credit=0, ...) ----> |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Synchronous Get"> |
| <p> |
| A synchronous get of a message from a Link is accomplished by incrementing the link-credit, |
| sending the updated <xref name="flow"/> state, and waiting indefinitely for a |
| <xref name="transfer"/> to arrive. |
| </p> |
| |
| <picture><![CDATA[ |
| Receiver Sender |
| ================================================================= |
| ... |
| flow(link-credit=1) ----------> |
| +---- transfer(...) |
| *block until transfer arrives* / |
| <---+ |
| ... |
| ----------------------------------------------------------------- |
| ]]> |
| </picture> |
| |
| <p> |
| Synchronous get with a timeout is accomplished by incrementing the link-credit, sending the |
| updated <xref name="flow"/> state and waiting for the link-credit to be consumed. When the |
| desired time has elapsed the Receiver then sets the drain flag and sends the newly updated |
| <xref name="flow"/> state again, while continuing to wait for the link-credit to be |
| consumed. Even if no messages are available, this condition will be met promptly because of |
| the drain flag. Once the link-credit is consumed, the Receiver can unambiguously determine |
| whether a message has arrived or whether the operation has timed out. |
| </p> |
| |
| <picture><![CDATA[ |
| Receiver Sender |
| ================================================================= |
| ... |
| flow(link-credit=1) ----------> |
| *wait for link-credit <= 0* |
| flow(drain=True) ---+ +--- transfer(...) |
| \ / |
| x |
| / \ |
| (1) <--+ +--> |
| (2) <---------- flow(...) |
| ... |
| ----------------------------------------------------------------- |
| (1) If a message is available within the timeout, it will |
| arrive at this point. |
| (2) If a message is not available within the timeout, the |
| drain flag will ensure that the Sender promptly advances the |
| delivery-count until link-credit is consumed. |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Asynchronous Notification"> |
| <p> |
| Asynchronous notification can be accomplished as follows. The receiver maintains a target |
| amount of link-credit for that Link. As <xref name="transfer">transfers</xref> arrive on the |
| Link, the Sender's link-credit decreases as the delivery-count increases. When the Sender's |
| link-credit falls below a threshold, the <xref name="flow"/> state may be sent to increase |
| the Sender's link-credit back to the desired target. |
| </p> |
| |
| <picture><![CDATA[ |
| Receiver Sender |
| ===================================================================== |
| ... |
| <---------- transfer(...) |
| <---------- transfer(...) |
| flow(link-credit=delta) ---+ +--- transfer(...) |
| \ / |
| x |
| / \ |
| <--+ +--> |
| <---------- transfer(...) |
| <---------- transfer(...) |
| flow(link-credit=delta) ---+ +--- transfer(...) |
| \ / |
| x |
| / \ |
| <--+ +--> |
| ... |
| --------------------------------------------------------------------- |
| The incoming message rate for the Link is limited by the |
| rate at which the Receiver updates the delivery-limit by |
| issuing link-credit. |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Stopping a Link"> |
| <p> |
| Stopping the transfers on a given Link is accomplished by updating the link-credit to be |
| zero and sending the updated <xref name="flow"/> state. Some transfers may be in-flight at |
| the time the <xref name="flow"/> state is sent, so incoming transfers may still arrive on |
| the Link. The echo field of the <xref name="flow"/> frame may be used to request the |
| Sender's <xref name="flow"/> state be echoed back. This may be used to determine when the |
| Link has finally quiesced. |
| </p> |
| |
| <picture><![CDATA[ |
| Receiver Sender |
| ================================================================ |
| ... |
| <---------- transfer(...) |
| flow(..., ---+ +--- transfer(...) |
| link-credit=0, \ / |
| echo=True) x |
| / \ |
| (1) <--+ +--> |
| (2) <---------- flow(...) |
| ... |
| ---------------------------------------------------------------- |
| (1) In-flight transfers may still arrive until the flow state |
| is updated at the Sender. |
| (2) At this point no further transfers will arrive. |
| ]]> |
| </picture> |
| </doc> |
| |
| <doc title="Messages"> |
| <p> |
| The transport layer assumes as little as possible about Messages and allows alternative |
| Message representations to be layered above. Message data is carried as the payload in |
| frames containing the <xref name="transfer"/> performative. Messages can be fragmented |
| across several <xref name="transfer"/> frames as indicated by the more flag of the <xref |
| name="transfer"/> performative. |
| </p> |
| </doc> |
| |
| <doc title="Transferring a Message"> |
| <p> |
| When an application initiates a message transfer, it assigns a delivery-tag used to track |
| the state of the delivery while the message is in transit. A delivery is considered |
| <i>unsettled</i> at the sender/receiver from the point at which it was sent/received until |
| it has been <i>settled</i> by the sending/receiving application. Each delivery MUST be |
| identified by a delivery-tag chosen by the sending application. The delivery-tag MUST be |
| unique amongst all deliveries that could be considered unsettled by either end of the Link. |
| </p> |
| |
| <p> |
| Upon initiating a transfer, the application will supply the sending link endpoint (Sender) |
| with the message data and its associated delivery-tag. The Sender will create an entry in |
| its unsettled map, and send a transfer frame that includes the delivery-tag, its initial |
| state, and its associated message data. For brevity on the wire, the delivery-tag is also |
| associated with a delivery-id assigned by the session. The delivery-id is then used to refer |
| to the delivery-tag in all subsequent interactions on that session. |
| </p> |
| |
| <p> |
| For simplicity the delivery-id is omitted in the following diagrams and the delivery-tag is |
| itself used directly. These diagrams also assume that this interaction takes place in the |
| context of a single established link, and as such omit other details that would be present |
| on the wire in practice such as the channel number, link handle, fragmentation flags, etc, |
| focusing only on the essential aspects of message transfer. |
| </p> |
| |
| <picture title="Initial Transfer"><![CDATA[ |
| +------------------+ |
| / Sender \ |
| +----------------------+ |
| | unsettled: | transfer(delivery-tag=DT, settled=False, |
| | ... | state=S_0, ...) |
| | DT -> (local: S_0, |-----------------------------------------------> |
| | remote: ?) | |
| | ... | |
| +----------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| Upon receiving the transfer, the receiving link endpoint (Receiver) will create an entry in |
| its own unsettled map and make the transferred message data available to the application to |
| process. |
| </p> |
| |
| <picture title="Initial Receipt"><![CDATA[ |
| +------------------+ |
| / Receiver \ |
| +----------------------+ |
| transfer(delivery-tag=DT, settled=False, | unsettled: | |
| state=S_0, ...) | ... | |
| ----------------------------------------------->| DT -> (local: S_1, | |
| | remote: S_0)| |
| | ... | |
| +----------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| Once notified of the received message data, the application processes the message, |
| indicating the updated delivery state to the link endpoint as desired. Applications may wish |
| to classify delivery states as <term>terminal</term> or <term>non-terminal</term> depending |
| on whether an endpoint will ever update the state further once it has been reached. In some |
| cases (e.g. large messages or transactions), the receiving application may wish to indicate |
| non-terminal delivery states to the sender. This is done via the <xref name="disposition"/> |
| frame. |
| </p> |
| |
| <picture title="Indication of Non-Terminal State"><![CDATA[ |
| +------------------+ |
| / Receiver \ |
| +----------------------+ |
| | unsettled: | |
| | ... | |
| <-----------------------------------------------| DT -> (local: S_2, | |
| disp(role=receiver, ..., delivery-tag=DT, | remote: S_0)| |
| settled=False, state=S_2, ...) | ... | |
| +----------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| Once the receiving application has finished processing the message, it indicates to the link |
| endpoint a <i>terminal</i> delivery state that reflects the outcome of the application |
| processing (successful or otherwise) and thus the outcome which the Receiver wishes to occur |
| at the Sender. This state is communicated back to the Sender via the disposition frame. |
| </p> |
| |
| <picture title="Indication of Presumptive Terminal State"><![CDATA[ |
| +------------------+ |
| / Receiver \ |
| +----------------------+ |
| | unsettled: | |
| | ... | |
| <-----------------------------------------------| DT -> (local: T_0, | |
| disp(role=receiver, ..., delivery-tag=DT, | remote: S_0)| |
| settled=False, state=T_0, ...) | ... | |
| +----------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| Upon receiving the updated delivery state from the Receiver, the Sender will, if it has not |
| already spontaneously attained a terminal state, update its view the state and communicate |
| this back to the sending application. |
| </p> |
| |
| <picture title="Receipt of Terminal State"><![CDATA[ |
| +------------------+ |
| / Sender \ |
| +----------------------+ |
| | unsettled: | |
| | ... | |
| | DT -> (local: S_0, |<----------------------------------------------- |
| | remote: T_0)| disp(role=receiver, ..., delivery-tag=DT, |
| | ... | settled=False, state=T_0, ...) |
| +----------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| The sending application will then typically perform some action based on this terminal state |
| and then settle the delivery, causing the Sender to remove the delivery-tag from its |
| unsettled map. The Sender will then send its final delivery state along with an indication |
| that the delivery is settled at the Sender. Note that this amounts to the Sender announcing |
| that it is forever forgetting everything about the delivery-tag in question, and as such it |
| is only possible to make such an announcement once, since after the Sender forgets, it has |
| no way of remembering to make the announcement again. Should this frame get lost due to an |
| interruption in communication, the Receiver will find out that the Sender has settled the |
| delivery upon link recovery. When the Sender re-attaches the Receiver will examine the |
| unsettled state of the Sender (i.e. what has <b>not</b> been forgotten) and from this can |
| derive that the delivery in question has been settled (since its tag will not be in the |
| unsettled state). |
| </p> |
| |
| <picture title="Indication of Settlement"><![CDATA[ |
| +------------------+ |
| / Sender \ |
| +----------------------+ |
| | unsettled: | disp(role=sender, ..., delivery-tag=DT, |
| | ... | settled=True, state=T_1, ...) |
| | - -> - |-----------------------------------------------> |
| | ... | |
| +----------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| When the Receiver finds out that the Sender has settled the delivery, the Receiver will |
| update its view of the remote state to indicate this, and then notify the receiving |
| application. |
| </p> |
| |
| <picture title="Receipt of Settlement"><![CDATA[ |
| +------------------+ |
| / Receiver \ |
| +----------------------+ |
| disp(role=sender, ..., delivery-tag=DT, | unsettled: | |
| settled=True, state=T_1, ...) | ... | |
| ----------------------------------------------->| DT -> (local: S_2, | |
| | remote: - ) | |
| | ... | |
| +----------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| The application may then perform some final action, e.g. remove the delivery-tag from a set |
| kept for de-duplication, and then notify the Receiver that the delivery is settled. The |
| Receiver will then remove the delivery-tag from its unsettled map. Note that because the |
| Receiver knows that the delivery is already settled at the Sender, it makes no effort to |
| notify the other endpoint that it is settling the delivery. |
| </p> |
| |
| <picture title="Final Settlement"><![CDATA[ |
| +------------------+ |
| / Receiver \ |
| +----------------------+ |
| | unsettled: | |
| | ... | |
| <-----------------------------------------------| - -> - | |
| | ... | |
| +----------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| As alluded to above, it is possible for the sending application to transition a delivery to |
| a terminal state at the Sender spontaneously (i.e. not as a consequence of a disposition |
| that has been received from the Receiver). In this case the Sender should send a disposition |
| to the Receiver, but not settle until the Receiver confirms, via a disposition in the |
| opposite direction, that it has updated the state at its endpoint. |
| </p> |
| |
| <p> |
| This set of exchanges illustrates the basic principals of message transfer. While a delivery |
| is unsettled the endpoints exchange the current state of the delivery. Eventually both |
| endpoints reach a terminal state as indicated by the application. This triggers the other |
| application to take some final action and settle the delivery, and once one endpoint |
| settles, this usually triggers the application at the other endpoint to settle. |
| </p> |
| |
| <p> |
| This basic pattern can be modified in a variety of ways to achieve different guarantees, for |
| example if the sending application settles the delivery <i>before</i> sending it, this |
| results in an <i>at-most-once</i> guarantee. The Sender has indicated up front with his |
| initial transmission that he has forgotten everything about this delivery and will therefore |
| make no further attempts to send it. Should this delivery make it to the Receiver, the |
| Receiver clearly has no obligation to respond with updates of the Receiver's delivery state, |
| as they would be meaningless and ignored by the Sender. |
| </p> |
| |
| <picture title="At-Most-Once"><![CDATA[ |
| +------------------+ |
| / Sender \ |
| +----------------------+ |
| | unsettled: | transfer(delivery-tag=DT, settled=True, |
| | ... | state=T_0, ...) |
| | - -> - |-----------------------------------------------> |
| | ... | |
| +----------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| Similarly, if we modify the basic scenario such that the receiving application chooses to |
| settle immediately upon processing the message rather than waiting for the sender to settle |
| first, we get an <i>at-least-once</i> guarantee. If the disposition frame indicated below is |
| lost, then upon link recovery the Sender will not see the delivery-tag in the Receiver's |
| unsettled map and will therefore assume the delivery was lost and resend it, resulting in |
| duplicate processing of the message at the Receiver. |
| </p> |
| |
| <picture title="At-Least-Once"><![CDATA[ |
| +------------------+ |
| / Receiver \ |
| +----------------------+ |
| | unsettled: | |
| | ... | |
| <-----------------------------------------------| - -> - | |
| disp(role=receiver, ..., delivery-tag=DT, | ... | |
| settled=True, state=T_0, ...) | | |
| +----------------------+ |
| ]]> |
| </picture> |
| |
| <p> |
| As one might guess, the scenario presented initially where the sending application settles |
| when the Receiver reaches a terminal state, and the receiving application settles when the |
| Sender settles, results in an <i>exactly-once</i> guarantee. More generally if the Receiver |
| settles prior to the Sender, it is possible for duplicate messages to occur, except in the |
| case where the Sender settles before his initial transmission. Similarly, if the Sender |
| settles before the Receiver reaches a terminal state, it is possible for messages to be |
| lost. |
| </p> |
| |
| <p> |
| The Sender and Receiver policy regarding settling may either be pre-configured for the |
| entire link, thereby allowing for optimized endpoint choices, or may be determined on an |
| ad-hoc basis for each delivery. An application may also choose to settle at an endpoint |
| independently of its delivery state, for example the sending application may choose to |
| settle a delivery due to the message ttl expiring regardless of whether the Receiver has |
| reached a terminal state. |
| </p> |
| |
| </doc> |
| |
| <doc name="resuming-deliveries" title="Resuming Deliveries"> |
| <p> |
| When a suspended link having unsettled deliveries is resumed, the <i>unsettled</i> field |
| from the <xref name="attach"/> frame will carry the delivery-tags and delivery state of all |
| deliveries considered unsettled by the issuing link endpoint. The set of delivery tags and |
| delivery states contained in the unsettled maps from both endpoints can be divided into |
| three categories: |
| </p> |
| |
| <dl> |
| <dt>Deliveries that only the Source considers unsettled</dt> |
| <dd><p>Deliveries in this category MAY be resumed at the discretion of the sending |
| application. If the sending application marks the resend attempt as a resumed delivery |
| then it MUST be ignored by the receiver. (This allows the sender to pipeline resumes |
| without risk of duplication at the sender).</p></dd> |
| |
| <dt>Deliveries that only the Target considers unsettled</dt> |
| <dd><p>Deliveries in this category MUST be ignored by the Sender, and MUST be considered |
| settled by the Receiver.</p></dd> |
| |
| <dt>Deliveries that both the Source and Target consider unsettled</dt> |
| <dd><p>Deliveries in this category MUST be resumed by the Sender.</p></dd> |
| </dl> |
| |
| <p> |
| Note that in the case where an endpoint indicates that the unsettled map is incomplete, the |
| absence of an entry in the unsettled map is not an indication of settlement. In this case |
| the two endpoints must reduce the levels of unsettled state as much as they can by the |
| Sender resuming and/or settling transfers that it observes that the Receiver considers |
| unsettled. Upon completion of this reduction of state, the two parties must suspend and |
| re-attempt to resume the link. Only when both sides have complete unsettled maps may new |
| unsettled state be created by the sending of non-resuming transfers. |
| </p> |
| |
| <p> |
| A delivery is resumed much the same way it is initially transferred with the following |
| exceptions: |
| </p> |
| |
| <ul> |
| <li><p>The resume flag of the <xref name="transfer"/> frame MUST be set to true when |
| resuming a delivery.</p></li> |
| <li><p>The Sender MAY omit message data when the Delivery State of the Receiver indicates |
| retransmission is unnecessary.</p></li> |
| </ul> |
| |
| <p> |
| Note that unsettled delivery-tags do NOT have any valid delivery-ids associated until they |
| are resumed, as the delivery-ids from their original link endpoints are meaningless to the |
| new link endpoints. |
| </p> |
| </doc> |
| |
| <doc title="Transferring Large Messages"> |
| <p> |
| Each <xref name="transfer"/> frame may carry an arbitrary amount of message data up to the |
| limit imposed by the maximum frame size. For Messages that are too large to fit within the |
| maximum frame size, additional data may be transferred in additional <xref name="transfer"/> |
| frames by setting the more flag on all but the last <xref name="transfer"/> frame. When a |
| message is split up into multiple <xref name="transfer"/> frames in this manner, messages |
| being transferred along different links MAY be interleaved. However, messages transferred |
| along a single link MUST NOT be interleaved. |
| </p> |
| |
| <p> |
| The sender may indicate an aborted attempt to deliver a Message by setting the abort flag on |
| the last <xref type="type" name="transfer"/>. In this case the receiver MUST discard the |
| Message data that was transferred prior to the abort. |
| </p> |
| |
| <picture title="Outgoing Fragmentation State Diagram"><![CDATA[ |
| +------------+ S:XFR(M=1,A=0) |
| +------| NOT_SENT |------+ |
| | +------------+ | |
| | | |
| | S:XFR(M=0,A=0) | |
| | | S:XFR(M=1,A=0) |
| | | +----------+ |
| | | | | |
| | \|/ \|/ | |
| | +------------+ | |
| | +----------------| SENDING |-------+ |
| | | S:XFR(M=0,A=0) +------------+ |
| | | | |
| | | | |
| | | | S:XFR(M=0,A=1) |
| | | | |
| \|/ \|/ \|/ |
| +------------+ +------------+ |
| | SENT | | ABORTED | |
| +------------+ +------------+ |
| |
| Key: S:XFR(M=?,A=?) --> Sent TRANSFER(more=?, aborted=?) |
| ]]> |
| </picture> |
| |
| <picture title="Incoming Fragmentation State Diagram"><![CDATA[ |
| +------------+ R:XFR(M=1,A=0) |
| +------| NOT_RCVD |------+ |
| | +------------+ | |
| | | |
| | R:XFR(M=0,A=0) | |
| | | R:XFR(M=1,A=0) |
| | | +----------+ |
| | | | | |
| | \|/ \|/ | |
| | +------------+ | |
| | +----------------| RECEIVING |-------+ |
| | | R:XFR(M=0,A=0) +------------+ |
| | | | |
| | | | |
| | | | R:XFR(M=0,A=1) |
| | | | |
| \|/ \|/ \|/ |
| +------------+ +------------+ |
| | RECEIVED | | ABORTED | |
| +------------+ +------------+ |
| |
| Key: R:XFR(M=?,A=?) --> Received TRANSFER(more=?, aborted=?) |
| ]]> |
| </picture> |
| </doc> |
| |
| </section> |
| |
| <section name="performatives" label="composite types that appear as frame bodies"> |
| |
| <!-- - Frame: open - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <type class="composite" name="open" source="list" provides="frame" |
| label="negotiate Connection parameters"> |
| <doc> |
| <p> |
| The first frame sent on a connection in either direction MUST contain an Open body. (Note |
| that the Connection header which is sent first on the Connection is *not* a frame.) The |
| fields indicate the capabilities and limitations of the sending peer. |
| </p> |
| </doc> |
| |
| <descriptor name="amqp:open:list" code="0x00000000:0x00000010"/> |
| |
| <field name="container-id" type="string" mandatory="true" |
| label="the id of the source container"/> |
| |
| <field name="hostname" type="string" label="the name of the target host"> |
| <doc> |
| <p> |
| The dns name of the host (either fully qualified or relative) to which the sending peer |
| is connecting. It is not mandatory to provide the hostname. If no hostname is provided |
| the receiving peer should select a default based on its own configuration. This field |
| can be used by AMQP proxies to determine the correct back-end service to connect |
| the client to. |
| </p> |
| |
| <p> |
| This field may already have been specified by the <xref name="sasl-init"/> frame, if a |
| SASL layer is used, or, the server name indication extension as described in |
| RFC-4366, if a TLS layer is used, in which case this field SHOULD be null or contain |
| the same value. It is undefined what a different value to those already specific means. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="max-frame-size" type="uint" default="4294967295" |
| label="proposed maximum frame size"> |
| <doc> |
| <p> |
| The largest frame size that the sending peer is able to accept on this Connection. If |
| this field is not set it means that the peer does not impose any specific limit. A peer |
| MUST NOT send frames larger than its partner can handle. A peer that receives an |
| oversized frame MUST close the Connection with the framing-error error-code. |
| </p> |
| |
| <p> |
| Both peers MUST accept frames of up to <xref name="MIN-MAX-FRAME-SIZE"/> octets |
| large. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="channel-max" type="ushort" default="65535" |
| label="the maximum channel number that may be used on the Connection"> |
| <doc> |
| <p> |
| The channel-max value is the highest channel number that may be used on the Connection. |
| This value plus one is the maximum number of Sessions that can be simultaneously active |
| on the Connection. A peer MUST not use channel numbers outside the range that its |
| partner can handle. A peer that receives a channel number outside the supported range |
| MUST close the Connection with the framing-error error-code. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="idle-time-out" type="milliseconds" label="idle time-out"> |
| <doc> |
| <p> |
| The idle time-out required by the sender. A value of zero is the same as if it was |
| not set (null). If the receiver is unable or unwilling to support the idle time-out |
| then it should close the connection with an error explaining why (eg, because it is |
| too small). |
| </p> |
| |
| <p> |
| If the value is not set, then the sender does not have an idle time-out. However, |
| senders doing this should be aware that implementations MAY choose to use an |
| internal default to efficiently manage a peer's resources. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="outgoing-locales" type="ietf-language-tag" multiple="true" |
| label="locales available for outgoing text"> |
| <doc> |
| <p> |
| A list of the locales that the peer supports for sending informational text. This |
| includes Connection, Session and Link error descriptions. A peer MUST support at least |
| the <i>en-US</i> locale (see <xref name="ietf-language-tag"/>). Since this value is |
| always supported, it need not be supplied in the outgoing-locales. A null value or an |
| empty list implies that only <i>en-US</i> is supported. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="incoming-locales" type="ietf-language-tag" multiple="true" |
| label="desired locales for incoming text in decreasing level of preference"> |
| <doc> |
| <p> |
| A list of locales that the sending peer permits for incoming informational text. This |
| list is ordered in decreasing level of preference. The receiving partner will chose the |
| first (most preferred) incoming locale from those which it supports. If none of the |
| requested locales are supported, <i>en-US</i> will be chosen. Note that <i>en-US</i> |
| need not be supplied in this list as it is always the fallback. A peer may determine |
| which of the permitted incoming locales is chosen by examining the partner's supported |
| locales as specified in the outgoing-locales field. A null value or an empty list |
| implies that only <i>en-US</i> is supported. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="offered-capabilities" type="symbol" multiple="true" |
| label="the extension capabilities the sender supports"> |
| <doc> |
| <p> |
| If the receiver of the offered-capabilities requires an extension capability which is |
| not present in the offered-capability list then it MUST close the connection. |
| </p> |
| <p> |
| A list of commonly defined connection capabilities and their meanings can be found here: |
| <xref type="extern" |
| name="http://www.amqp.org/specification/1.0/connection-capabilities"/>. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="desired-capabilities" type="symbol" multiple="true" |
| label="the extension capabilities the sender may use if the receiver supports them"> |
| <doc> |
| <p> |
| The desired-capability list defines which extension capabilities the sender MAY use if |
| the receiver offers them (i.e. they are in the offered-capabilities list received by the |
| sender of the desired-capabilities). If the receiver of the desired-capabilities offers |
| extension capabilities which are not present in the desired-capability list it received, |
| then it can be sure those (undesired) capabilities will not be used on the |
| Connection. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="properties" type="fields" label="connection properties"> |
| <doc> |
| <p> |
| The properties map contains a set of fields intended to indicate information about the |
| connection and its container. |
| </p> |
| <p> |
| A list of commonly defined connection properties and their meanings can be found here: |
| <xref type="extern" name="http://www.amqp.org/specification/1.0/connection-properties"/> |
| </p> |
| </doc> |
| </field> |
| </type> |
| |
| <!-- - Frame: begin - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <type class="composite" name="begin" source="list" provides="frame" |
| label="begin a Session on a channel"> |
| <doc> |
| <p> |
| Indicate that a Session has begun on the channel. |
| </p> |
| </doc> |
| |
| <descriptor name="amqp:begin:list" code="0x00000000:0x00000011"/> |
| |
| <field name="remote-channel" type="ushort" label="the remote channel for this Session"> |
| <doc> |
| <p> |
| If a Session is locally initiated, the remote-channel MUST NOT be set. When an endpoint |
| responds to a remotely initiated Session, the remote-channel MUST be set to the channel |
| on which the remote Session sent the begin. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="next-outgoing-id" type="transfer-number" mandatory="true" |
| label="the transfer-id of the first transfer id the sender will send"> |
| <doc> |
| <p>See <xref type="doc" name="session-flow-control"/>.</p> |
| </doc> |
| </field> |
| |
| <field name="incoming-window" type="uint" mandatory="true" |
| label="the initial incoming-window of the sender"> |
| <doc> |
| <p>See <xref name="session-flow-control"/>.</p> |
| </doc> |
| </field> |
| |
| <field name="outgoing-window" type="uint" mandatory="true" |
| label="the initial outgoing-window of the sender"> |
| <doc> |
| <p>See <xref name="session-flow-control"/>.</p> |
| </doc> |
| </field> |
| |
| <field name="handle-max" type="handle" default="4294967295" |
| label="the maximum handle value that may be used on the Session"> |
| <doc> |
| <p> |
| The handle-max value is the highest handle value that may be used on the Session. |
| A peer MUST NOT attempt to attach a Link using a handle value outside the range that its |
| partner can handle. A peer that receives a handle outside the supported range MUST close |
| the Connection with the framing-error error-code. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="offered-capabilities" type="symbol" multiple="true" |
| label="the extension capabilities the sender supports"> |
| <doc> |
| <p> |
| A list of commonly defined session capabilities and their meanings can be found here: |
| <xref type="extern" name="http://www.amqp.org/specification/1.0/session-capabilities"/>. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="desired-capabilities" type="symbol" multiple="true" |
| label="the extension capabilities the sender may use if the receiver supports them"/> |
| |
| <field name="properties" type="fields" label="session properties"> |
| <doc> |
| <p> |
| The properties map contains a set of fields intended to indicate information about the |
| session and its container. |
| </p> |
| <p> |
| A list of commonly defined session properties and their meanings can be found here: |
| <xref type="extern" name="http://www.amqp.org/specification/1.0/session-properties"/>. |
| </p> |
| </doc> |
| </field> |
| </type> |
| |
| <!-- - Frame: attach - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <type class="composite" name="attach" source="list" provides="frame" |
| label="attach a Link to a Session"> |
| <doc> |
| <p> |
| The <xref type="type" name="attach"/> frame indicates that a Link Endpoint has been |
| attached to the Session. The opening flag is used to indicate that the Link Endpoint is |
| newly created. |
| </p> |
| </doc> |
| |
| <descriptor name="amqp:attach:list" code="0x00000000:0x00000012"/> |
| |
| <field name="name" type="string" mandatory="true" label="the name of the link"> |
| <doc> |
| <p> |
| This name uniquely identifies the link from the container of the source to the container |
| of the target node, e.g. if the container of the source node is A, and the container of |
| the target node is B, the link may be globally identified by the (ordered) tuple |
| <i>(A,B,<name>)</i>. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="handle" type="handle" mandatory="true"> |
| <doc> |
| <p> |
| The handle MUST NOT be used for other open Links. An attempt to attach using a handle |
| which is already associated with a Link MUST be responded to with an immediate |
| <xref name="close"/> carrying a Handle-in-use <xref name="session-error"/>. |
| </p> |
| <p> |
| To make it easier to monitor AMQP link attach frames, it is recommended that |
| implementations always assign the lowest available handle to this field. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="role" type="role" mandatory="true" label="role of the link endpoint"/> |
| |
| <field name="snd-settle-mode" type="sender-settle-mode" default="mixed" |
| label="settlement mode for the Sender"> |
| |
| <doc> |
| <p> |
| Determines the settlement policy for deliveries sent at the Sender. When set at the |
| Receiver this indicates the desired value for the settlement mode at the Sender. When |
| set at the Sender this indicates the actual settlement mode in use. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="rcv-settle-mode" type="receiver-settle-mode" default="first" |
| label="the settlement mode of the Receiver"> |
| <doc> |
| <p> |
| Determines the settlement policy for unsettled deliveries received at the Receiver. When |
| set at the Sender this indicates the desired value for the settlement mode at the |
| Receiver. When set at the Receiver this indicates the actual settlement mode in use. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="source" type="*" requires="source" label="the source for Messages"> |
| <doc> |
| <p> |
| If no source is specified on an outgoing Link, then there is no source currently |
| attached to the Link. A Link with no source will never produce outgoing Messages. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="target" type="*" requires="target" label="the target for Messages"> |
| <doc> |
| <p> |
| If no target is specified on an incoming Link, then there is no target currently |
| attached to the Link. A Link with no target will never permit incoming Messages. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="unsettled" type="map" label="unsettled delivery state"> |
| <doc> |
| <p> |
| This is used to indicate any unsettled delivery states when a suspended link is resumed. |
| The map is keyed by delivery-tag with values indicating the delivery state. The local |
| and remote delivery states for a given delivery-tag MUST be compared to resolve any |
| in-doubt deliveries. If necessary, deliveries MAY be resent, or resumed based on the |
| outcome of this comparison. See <xref name="resuming-deliveries"/>. |
| </p> |
| |
| <p> |
| If the local unsettled map is too large to be encoded within a frame of the agreed |
| maximum frame size then the session may be ended with the frame-size-too-small error |
| (see <xref name="amqp-error"/>). The endpoint SHOULD make use of the ability to send an |
| incomplete unsettled map (see below) to avoid sending an error. |
| </p> |
| |
| <p> |
| The unsettled map MUST NOT contain null valued keys. |
| </p> |
| |
| <p> |
| When reattaching (as opposed to resuming), the unsettled map MUST be null. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="incomplete-unsettled" type="boolean" default="false"> |
| <doc> |
| <p> |
| If set to true this field indicates that the unsettled map provided is not complete. |
| When the map is incomplete the recipient of the map cannot take the absence of a |
| delivery tag from the map as evidence of settlement. On receipt of an incomplete |
| unsettled map a sending endpoint MUST NOT send any new deliveries (i.e. deliveries where |
| resume is not set to true) to its partner (and a receiving endpoint which sent an |
| incomplete unsettled map MUST detach with an error on receiving a transfer which does |
| not have the resume flag set to true). |
| </p> |
| </doc> |
| </field> |
| |
| <field name="initial-delivery-count" type="sequence-no"> |
| <doc> |
| <p> |
| This MUST NOT be null if role is sender, and it is ignored if the role is receiver. See |
| <xref name="flow-control"/>. |
| </p> |
| </doc> |
| </field> |
| |
| |
| <field name="max-message-size" type="ulong" |
| label="the maximum message size supported by the link endpoint"> |
| <doc> |
| <p> |
| This field indicates the maximum message size supported by the link endpoint. Any |
| attempt to deliver a message larger than this results in a message-size-exceeded |
| <xref name="link-error"/>. If this field is zero or unset, there is no maximum size |
| imposed by the link endpoint. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="offered-capabilities" type="symbol" multiple="true" |
| label="the extension capabilities the sender supports"> |
| <doc> |
| <p> |
| A list of commonly defined session capabilities and their meanings can be found here: |
| <xref type="extern" name="http://www.amqp.org/specification/1.0/link-capabilities"/>. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="desired-capabilities" type="symbol" multiple="true" |
| label="the extension capabilities the sender may use if the receiver supports them"/> |
| |
| <field name="properties" type="fields" label="link properties"> |
| <doc> |
| <p> |
| The properties map contains a set of fields intended to indicate information about the |
| link and its container. |
| </p> |
| <p> |
| A list of commonly defined link properties and their meanings can be found here: |
| <xref type="extern" name="http://www.amqp.org/specification/1.0/link-properties"/> |
| </p> |
| </doc> |
| </field> |
| </type> |
| |
| <!-- - Frame: flow - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <type class="composite" name="flow" source="list" provides="frame" label="update link state"> |
| <doc> |
| <p>Updates the flow state for the specified Link.</p> |
| </doc> |
| |
| <descriptor name="amqp:flow:list" code="0x00000000:0x00000013"/> |
| |
| <field name="next-incoming-id" type="transfer-number"> |
| <doc> |
| <p> |
| Identifies the expected transfer-id of the next incoming <xref name="transfer"/> frame. |
| This value is not set if and only if the sender has not yet received the |
| <xref name="begin"/> frame for the session. See |
| <xref type="doc" name="session-flow-control"/> for more details. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="incoming-window" type="uint" mandatory="true"> |
| <doc> |
| <p> |
| Defines the maximum number of incoming <xref name="transfer"/> frames that the endpoint |
| can currently receive. See <xref type="doc" name="session-flow-control"/> for more |
| details. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="next-outgoing-id" type="transfer-number" mandatory="true"> |
| <doc> |
| <p> |
| The transfer-id that will be assigned to the next outgoing <xref name="transfer"/> |
| frame. See <xref type="doc" name="session-flow-control"/> for more details. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="outgoing-window" type="uint" mandatory="true"> |
| <doc> |
| <p> |
| Defines the maximum number of outgoing <xref name="transfer"/> frames that the endpoint |
| could potentially currently send, if it was not constrained by restrictions imposed by |
| its peer's incoming-window. See <xref type="doc" name="session-flow-control"/> for more |
| details. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="handle" type="handle"> |
| <doc> |
| <p> |
| If set, indicates that the flow frame carries flow state information for the local Link |
| Endpoint associated with the given handle. If not set, the flow frame is carrying only |
| information pertaining to the Session Endpoint. |
| </p> |
| <p> |
| If set to a handle that is not currently associated with an attached Link, the |
| recipient MUST respond by ending the session with an <xref choice="unattached-handle" |
| name="session-error"/> session error. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="delivery-count" type="sequence-no" label="the endpoint's delivery-count"> |
| <doc> |
| <p> |
| When the handle field is not set, this field MUST NOT be set. |
| </p> |
| <p> |
| When the handle identifies that the flow state is being sent from the Sender Link |
| Endpoint to Receiver Link Endpoint this field MUST be set to the current delivery-count |
| of the Link Endpoint. |
| </p> |
| <p> |
| When the flow state is being sent from the Receiver Endpoint to the Sender Endpoint this |
| field MUST be set to the last known value of the corresponding Sending Endpoint. In the |
| event that the Receiving Link Endpoint has not yet seen the initial |
| <xref name="attach"/> frame from the Sender this field MUST NOT be set. |
| </p> |
| <p> |
| See <xref type="doc" name="flow-control"/> for more details. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="link-credit" type="uint" |
| label="the current maximum number of Messages that can be received"> |
| <doc> |
| <p> |
| The current maximum number of Messages that can be handled at the Receiver |
| Endpoint of the Link. Only the receiver endpoint can independently set this value. The |
| sender endpoint sets this to the last known value seen from the receiver. See |
| <xref type="doc" name="flow-control"/> for more details. |
| </p> |
| <p> |
| When the handle field is not set, this field MUST NOT be set. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="available" type="uint" label="the number of available Messages"> |
| <doc> |
| <p> |
| The number of Messages awaiting credit at the link sender endpoint. Only the |
| sender can independently set this value. The receiver sets this to the last known value |
| seen from the sender. See <xref type="doc" name="flow-control"/> for more details. |
| </p> |
| <p> |
| When the handle field is not set, this field MUST NOT be set. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="drain" type="boolean" default="false" label="indicates drain mode"> |
| <doc> |
| <p> |
| When flow state is sent from the sender to the receiver, this field contains the actual |
| drain mode of the sender. When flow state is sent from the receiver to the sender, this |
| field contains the desired drain mode of the receiver. See <xref type="doc" |
| name="flow-control"/> for more details. |
| </p> |
| <p> |
| When the handle field is not set, this field MUST NOT be set. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="echo" type="boolean" default="false" |
| label="request link state from other endpoint"/> |
| |
| <field name="properties" type="fields" label="link state properties"> |
| <doc> |
| <p> |
| A list of commonly defined link state properties and their meanings can be found here: |
| <xref type="extern" name="http://www.amqp.org/specification/1.0/link-state-properties"/> |
| </p> |
| </doc> |
| </field> |
| </type> |
| |
| <!-- - Frame: transfer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <type class="composite" name="transfer" source="list" provides="frame" |
| label="transfer a Message"> |
| <doc> |
| <p> |
| The transfer frame is used to send Messages across a Link. Messages may be carried by a |
| single transfer up to the maximum negotiated frame size for the Connection. Larger |
| Messages may be split across several transfer frames. |
| </p> |
| </doc> |
| |
| <descriptor name="amqp:transfer:list" code="0x00000000:0x00000014"/> |
| |
| <field name="handle" type="handle" mandatory="true"> |
| <doc> |
| <p>Specifies the Link on which the Message is transferred.</p> |
| </doc> |
| </field> |
| |
| <field name="delivery-id" type="delivery-number" label="alias for delivery-tag"> |
| <doc> |
| <p> |
| The delivery-id MUST be supplied on the first transfer of a multi-transfer delivery. On |
| continuation transfers the delivery-id MAY be omitted. It is an error if the delivery-id |
| on a continuation transfer differs from the delivery-id on the first transfer of a |
| delivery. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="delivery-tag" type="delivery-tag"> |
| <doc> |
| <p> |
| Uniquely identifies the delivery attempt for a given Message on this Link. This field |
| MUST be specified for the first transfer of a multi transfer message and may only be |
| omitted for continuation transfers. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="message-format" type="message-format" label="indicates the message format"> |
| <doc> |
| <p> |
| This field MUST be specified for the first transfer of a multi transfer message and may |
| only be omitted for continuation transfers. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="settled" type="boolean"> |
| <doc> |
| <p> |
| If not set on the first (or only) transfer for a delivery, then the settled flag MUST |
| be interpreted as being false. For subsequent transfers if the settled flag is left |
| unset then it MUST be interpreted as true if and only if the value of the settled flag |
| on any of the preceding transfers was true; if no preceding transfer was sent with |
| settled being true then the value when unset MUST be taken as false. |
| </p> |
| <p> |
| If the negotiated value for snd-settle-mode at attachment is <xref |
| name="sender-settle-mode" choice="settled"/>, then this field MUST be true on at least |
| one transfer frame for a delivery (i.e. the delivery must be settled at the Sender at |
| the point the delivery has been completely transferred). |
| </p> |
| <p> |
| If the negotiated value for snd-settle-mode at attachment is <xref |
| name="sender-settle-mode" choice="unsettled"/>, then this field MUST be false (or |
| unset) on every transfer frame for a delivery (unless the delivery is aborted). |
| </p> |
| </doc> |
| </field> |
| |
| <field name="more" type="boolean" default="false" |
| label="indicates that the Message has more content"> |
| <doc> |
| <p> |
| Note that if both the more and aborted fields are set to true, the aborted flag takes |
| precedence. That is a receiver should ignore the value of the more field if the |
| transfer is marked as aborted. A sender SHOULD NOT set the more flag to true if it |
| also sets the aborted flag to true. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="rcv-settle-mode" type="receiver-settle-mode"> |
| <doc> |
| <p> |
| If <xref name="receiver-settle-mode" choice="first"/>, this indicates that the |
| Receiver MUST settle the delivery once it has arrived without waiting for the Sender to |
| settle first. |
| </p> |
| <p> |
| If <xref name="receiver-settle-mode" choice="second"/>, this indicates that the |
| Receiver MUST NOT settle until sending its disposition to the Sender and receiving a |
| settled disposition from the sender. |
| </p> |
| <p> |
| If not set, this value is defaulted to the value negotiated on link attach. |
| </p> |
| <p> |
| If the negotiated link value is <xref name="receiver-settle-mode" choice="first"/>, |
| then it is illegal to set this field to <xref name="receiver-settle-mode" |
| choice="second"/>. |
| </p> |
| <p> |
| If the message is being sent settled by the Sender, the value of this field is ignored. |
| </p> |
| <p> |
| The (implicit or explicit) value of this field does not form part of the transfer state, |
| and is not retained if a link is suspended and subsequently resumed. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="state" type="*" requires="delivery-state" |
| label="the state of the delivery at the sender"> |
| <doc> |
| <p> |
| When set this informs the receiver of the state of the delivery at the sender. This is |
| particularly useful when transfers of unsettled deliveries are resumed after a resuming |
| a link. Setting the state on the transfer can be thought of as being equivalent to |
| sending a disposition immediately before the <xref name="transfer"/> performative, i.e. |
| it is the state of the delivery (not the transfer) that existed at the point the frame |
| was sent. |
| </p> |
| <p> |
| Note that if the <xref name="transfer"/> performative (or an earlier <xref |
| name="disposition"/> performative referring to the delivery) indicates that the delivery |
| has attained a terminal state, then no future <xref name="transfer"/> or <xref |
| name="disposition"/> sent by the sender can alter that terminal state. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="resume" type="boolean" default="false" label="indicates a resumed delivery"> |
| <doc> |
| <p> |
| If true, the resume flag indicates that the transfer is being used to reassociate an |
| unsettled delivery from a dissociated link endpoint. See |
| <xref name="resuming-deliveries"/> for more details. |
| </p> |
| <p> |
| The receiver MUST ignore resumed deliveries that are not in its local unsettled map. The |
| sender MUST NOT send resumed transfers for deliveries not in its local unsettled map. |
| </p> |
| <p> |
| If a resumed delivery spans more than one transfer performative, then the resume flag |
| MUST be set to true on the first transfer of the resumed delivery. For subsequent |
| transfers for the same delivery the resume flag may be set to true, or may be omitted. |
| </p> |
| <p> |
| In the case where the exchange of unsettled maps makes clear that all message data has |
| been successfully transferred to the receiver, and that only the final state (and |
| potentially settlement) at the sender needs to be conveyed, then a resumed delivery may |
| carry no payload and instead act solely as a vehicle for carrying the terminal state of |
| the delivery at the sender. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="aborted" type="boolean" default="false" |
| label="indicates that the Message is aborted"> |
| <doc> |
| <p> |
| Aborted Messages should be discarded by the recipient (any payload within the frame |
| carrying the performative MUST be ignored). An aborted Message is implicitly settled. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="batchable" type="boolean" default="false" label="batchable hint"> |
| <doc> |
| <p> |
| If true, then the issuer is hinting that there is no need for the peer to urgently |
| communicate updated delivery state. This hint may be used to artificially increase the |
| amount of batching an implementation uses when communicating delivery states, and |
| thereby save bandwidth. |
| </p> |
| <p> |
| If the message being delivered is too large to fit within a single frame, then the |
| setting of batchable to true on any of the <xref name="transfer"/> performatives for the |
| delivery is equivalent to setting batchable to true for all the <xref name="transfer"/> |
| performatives for the delivery. |
| </p> |
| <p> |
| The batchable value does not form part of the transfer state, and is not retained if |
| a link is suspended and subsequently resumed. |
| </p> |
| </doc> |
| </field> |
| </type> |
| |
| <!-- - Frame: disposition - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <type class="composite" name="disposition" source="list" provides="frame" |
| label="inform remote peer of delivery state changes"> |
| <doc> |
| <p> |
| The disposition frame is used to inform the remote peer of local changes in the state of |
| deliveries. The disposition frame may reference deliveries from many different links |
| associated with a session, although all links MUST have the directionality indicated by |
| the specified <i>role</i>. |
| </p> |
| <p> |
| Note that it is possible for a disposition sent from sender to receiver to refer to a |
| delivery which has not yet completed (i.e. a delivery which is spread over multiple |
| frames and not all frames have yet been sent). The use of such interleaving is |
| discouraged in favor of carrying the modified state on the next <xref name="transfer"/> |
| performative for the delivery. |
| </p> |
| <p> |
| The disposition performative may refer to deliveries on links that are no longer attached. |
| As long as the links have not been closed or detached with an error then the deliveries |
| are still "live" and the updated state MUST be applied. |
| </p> |
| </doc> |
| |
| <descriptor name="amqp:disposition:list" code="0x00000000:0x00000015"/> |
| |
| <field name="role" type="role" mandatory="true" label="directionality of disposition"> |
| <doc> |
| <p> |
| The role identifies whether the disposition frame contains information |
| about <i>sending</i> link endpoints or <i>receiving</i> link endpoints. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="first" type="delivery-number" mandatory="true" label="lower bound of deliveries"> |
| <doc> |
| <p> |
| Identifies the lower bound of delivery-ids for the deliveries in this set. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="last" type="delivery-number" label="upper bound of deliveries"> |
| <doc> |
| <p> |
| Identifies the upper bound of delivery-ids for the deliveries in this set. If not set, |
| this is taken to be the same as <i>first</i>. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="settled" type="boolean" default="false" label="indicates deliveries are settled"> |
| <doc> |
| <p> |
| If true, indicates that the referenced deliveries are considered settled by the issuing |
| endpoint. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="state" type="*" requires="delivery-state" label="indicates state of deliveries"> |
| <doc> |
| <p> |
| Communicates the state of all the deliveries referenced by this disposition. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="batchable" type="boolean" default="false" label="batchable hint"> |
| <doc> |
| <p> |
| If true, then the issuer is hinting that there is no need for the peer to urgently |
| communicate the impact of the updated delivery states. This hint may be used to |
| artificially increase the amount of batching an implementation uses when communicating |
| delivery states, and thereby save bandwidth. |
| </p> |
| </doc> |
| </field> |
| </type> |
| |
| <!-- - Frame: detach - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <type class="composite" name="detach" source="list" provides="frame" |
| label="detach the Link Endpoint from the Session" > |
| <doc> |
| <p> |
| Detach the Link Endpoint from the Session. This un-maps the handle and makes it available |
| for use by other Links. |
| </p> |
| </doc> |
| |
| <descriptor name="amqp:detach:list" code="0x00000000:0x00000016"/> |
| |
| <field name="handle" type="handle" mandatory="true" |
| label="the local handle of the link to be detached"/> |
| |
| <field name="closed" type="boolean" default="false" |
| label="if true then the sender has closed the link"> |
| <doc> |
| <p>See <xref name="closing-a-link"/>.</p> |
| </doc> |
| </field> |
| |
| <field name="error" type="error" label="error causing the detach"> |
| <doc> |
| <p> |
| If set, this field indicates that the Link is being detached due to an error condition. |
| The value of the field should contain details on the cause of the error. |
| </p> |
| </doc> |
| </field> |
| </type> |
| |
| <!-- - Frame: end - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <type class="composite" name="end" source="list" provides="frame" label="end the Session"> |
| <doc> |
| <p>Indicates that the Session has ended.</p> |
| </doc> |
| |
| <descriptor name="amqp:end:list" code="0x00000000:0x00000017"/> |
| |
| <field name="error" type="error" label="error causing the end"> |
| <doc> |
| <p> |
| If set, this field indicates that the Session is being ended due to an error condition. |
| The value of the field should contain details on the cause of the error. |
| </p> |
| </doc> |
| </field> |
| </type> |
| |
| <!-- - Frame: close - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <type class="composite" name="close" source="list" provides="frame" |
| label="signal a Connection close"> |
| <doc> |
| <p> |
| Sending a close signals that the sender will not be sending any more frames (or bytes of |
| any other kind) on the Connection. Orderly shutdown requires that this frame MUST be |
| written by the sender. It is illegal to send any more frames (or bytes of any other kind) |
| after sending a close frame. |
| </p> |
| </doc> |
| |
| <descriptor name="amqp:close:list" code="0x00000000:0x00000018"/> |
| |
| <field name="error" type="error" label="error causing the close"> |
| <doc> |
| <p> |
| If set, this field indicates that the Connection is being closed due to an error |
| condition. The value of the field should contain details on the cause of the error. |
| </p> |
| </doc> |
| </field> |
| </type> |
| |
| </section> |
| |
| <section name="definitions" label="supporting definitions"> |
| |
| <type class="restricted" name="role" source="boolean" label="link endpoint role"> |
| <choice name="sender" value="false" /> |
| <choice name="receiver" value="true" /> |
| </type> |
| |
| <type class="restricted" name="sender-settle-mode" source="ubyte" |
| label="settlement policy for a Sender"> |
| <choice name="unsettled" value="0"> |
| <doc> |
| <p> |
| The Sender will send all deliveries initially unsettled to the Receiver. |
| </p> |
| </doc> |
| </choice> |
| <choice name="settled" value="1"> |
| <doc> |
| <p> |
| The Sender will send all deliveries settled to the Receiver. |
| </p> |
| </doc> |
| </choice> |
| <choice name="mixed" value="2"> |
| <doc> |
| <p> |
| The Sender may send a mixture of settled and unsettled deliveries to the Receiver. |
| </p> |
| </doc> |
| </choice> |
| </type> |
| |
| <type class="restricted" name="receiver-settle-mode" source="ubyte" |
| label="settlement policy for a Receiver"> |
| <choice name="first" value="0"> |
| <doc> |
| <p> |
| The Receiver will spontaneously settle all incoming transfers. |
| </p> |
| </doc> |
| </choice> |
| <choice name="second" value="1"> |
| <doc> |
| <p> |
| The Receiver will only settle after sending the <xref name="disposition"/> to the Sender |
| and receiving a <xref name="disposition"/> indicating settlement of the delivery from |
| the sender. |
| </p> |
| </doc> |
| </choice> |
| </type> |
| |
| <type class="restricted" name="handle" source="uint" label="the handle of a Link"> |
| <doc> |
| <p> |
| An alias established by the <xref type="type" name="attach"/> frame and subsequently used |
| by endpoints as a shorthand to refer to the Link in all outgoing frames. The two endpoints |
| may potentially use different handles to refer to the same Link. Link handles may be |
| reused once a Link is closed for both send and receive. |
| </p> |
| </doc> |
| </type> |
| |
| <type class="restricted" name="seconds" source="uint" label="a duration measured in seconds"/> |
| |
| <type class="restricted" name="milliseconds" source="uint" |
| label="a duration measured in milliseconds"/> |
| |
| <type class="restricted" name="delivery-tag" source="binary"> |
| <doc> |
| <p> |
| A delivery-tag may be up to 32 octets of binary data. |
| </p> |
| </doc> |
| </type> |
| |
| <type class="restricted" name="delivery-number" source="sequence-no"/> |
| |
| <type class="restricted" name="transfer-number" source="sequence-no"/> |
| |
| <type class="restricted" name="sequence-no" source="uint" label="32-bit RFC-1982 serial number"> |
| <doc> |
| <p> |
| A sequence-no encodes a serial number as defined in RFC-1982. The arithmetic, and |
| operators for these numbers are defined by RFC-1982. |
| </p> |
| </doc> |
| </type> |
| |
| <type class="restricted" name="message-format" source="uint" label="32-bit message format code"> |
| <doc> |
| <p> |
| The upper three octets of a message format code identify a particular message format. The |
| lowest octet indicates the version of said message format. Any given version of a format |
| is forwards compatible with all higher versions. |
| </p> |
| |
| <picture><![CDATA[ |
| 3 octets 1 octet |
| +----------------+---------+ |
| | message format | version | |
| +----------------+---------+ |
| | | |
| msb lsb |
| ]]> |
| </picture> |
| </doc> |
| </type> |
| |
| <type class="restricted" name="ietf-language-tag" source="symbol" |
| label="an IETF language tag as defined by BCP 47"> |
| <doc> |
| <p> |
| IETF language tags are abbreviated language codes as defined in the IETF Best Current |
| Practice <xref type="extern" name="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">BCP-47 |
| </xref> (incorporating <xref type="extern" |
| name="http://www.rfc-editor.org/rfc/rfc5646.txt">RFC-5646</xref>). A list of registered |
| subtags is maintained in the <xref type="extern" |
| name="http://www.iana.org/assignments/language-subtag-registry">IANA Language Subtag |
| Registry</xref>. |
| </p> |
| <p> |
| All AMQP implementations should understand at the least the IETF language tag |
| <i>en-US</i> (note that this uses a hyphen separator, not an underscore). |
| </p> |
| </doc> |
| </type> |
| |
| <type class="restricted" name="fields" source="map" label="a mapping from field name to value"> |
| <doc> |
| <p> |
| The <i>fields</i> type is a map where the keys are restricted to be of type <xref |
| name="symbol"/> (this excludes the possibility of a null key). There is no further |
| restriction implied by the <i>fields</i> type on the allowed values for the entries or the |
| set of allowed keys. |
| </p> |
| </doc> |
| </type> |
| |
| <type class="composite" name="error" source="list" label="details of an error"> |
| |
| <descriptor name="amqp:error:list" code="0x00000000:0x0000001d"/> |
| |
| <field name="condition" type="symbol" requires="error-condition" mandatory="true" |
| label="error condition"> |
| <doc> |
| <p>A symbolic value indicating the error condition.</p> |
| </doc> |
| </field> |
| |
| <field name="description" type="string" label="descriptive text about the error condition"> |
| <doc> |
| <p> |
| This text supplies any supplementary details not indicated by the condition field. This |
| text can be logged as an aid to resolving issues. |
| </p> |
| </doc> |
| </field> |
| |
| <field name="info" type="fields" label="map carrying information about the error condition"/> |
| </type> |
| |
| <type class="restricted" name="amqp-error" source="symbol" provides="error-condition" |
| label="shared error conditions"> |
| |
| <choice name="internal-error" value="amqp:internal-error"> |
| <doc> |
| <p> |
| An internal error occurred. Operator intervention may be required to resume normal |
| operation. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="not-found" value="amqp:not-found"> |
| <doc> |
| <p>A peer attempted to work with a remote entity that does not exist.</p> |
| </doc> |
| </choice> |
| |
| <choice name="unauthorized-access" value="amqp:unauthorized-access"> |
| <doc> |
| <p> |
| A peer attempted to work with a remote entity to which it has no access due to security |
| settings. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="decode-error" value="amqp:decode-error"> |
| <doc> |
| <p>Data could not be decoded.</p> |
| </doc> |
| </choice> |
| |
| <choice name="resource-limit-exceeded" value="amqp:resource-limit-exceeded"> |
| <doc> |
| <p>A peer exceeded its resource allocation.</p> |
| </doc> |
| </choice> |
| |
| <choice name="not-allowed" value="amqp:not-allowed"> |
| <doc> |
| <p> |
| The peer tried to use a frame in a manner that is inconsistent with the semantics |
| defined in the specification. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="invalid-field" value="amqp:invalid-field"> |
| <doc> |
| <p> |
| An invalid field was passed in a frame body, and the operation could not proceed. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="not-implemented" value="amqp:not-implemented"> |
| <doc> |
| <p>The peer tried to use functionality that is not implemented in its partner.</p> |
| </doc> |
| </choice> |
| |
| <choice name="resource-locked" value="amqp:resource-locked"> |
| <doc> |
| <p> |
| The client attempted to work with a server entity to which it has no access because |
| another client is working with it. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="precondition-failed" value="amqp:precondition-failed"> |
| <doc> |
| <p> |
| The client made a request that was not allowed because some precondition failed. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="resource-deleted" value="amqp:resource-deleted"> |
| <doc> |
| <p>A server entity the client is working with has been deleted.</p> |
| </doc> |
| </choice> |
| |
| <choice name="illegal-state" value="amqp:illegal-state"> |
| <doc> |
| <p> |
| The peer sent a frame that is not permitted in the current state of the Session. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="frame-size-too-small" value="amqp:frame-size-too-small"> |
| <doc> |
| <p> |
| The peer cannot send a frame because the smallest encoding of the performative with the |
| currently valid values would be too large to fit within a frame of the agreed maximum |
| frame size. When transferring a message the message data can be sent in multiple <xref |
| name="transfer"/> frames thereby avoiding this error. Similarly when attaching a link |
| with a large unsettled map the endpoint may make use of the incomplete-unsettled flag to |
| avoid the need for overly large frames. |
| </p> |
| </doc> |
| </choice> |
| </type> |
| |
| <type class="restricted" name="connection-error" source="symbol" provides="error-condition" |
| label="symbols used to indicate connection error conditions"> |
| |
| <choice name="connection-forced" value="amqp:connection:forced"> |
| <doc> |
| <p> |
| An operator intervened to close the Connection for some reason. The client may retry at |
| some later date. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="framing-error" value="amqp:connection:framing-error"> |
| <doc> |
| <p>A valid frame header cannot be formed from the incoming byte stream.</p> |
| </doc> |
| </choice> |
| |
| <choice name="redirect" value="amqp:connection:redirect"> |
| <doc> |
| <p> |
| The container is no longer available on the current connection. The peer should |
| attempt reconnection to the container using the details provided in the info map. |
| </p> |
| <dl> |
| <dt>hostname</dt> |
| <dd> |
| <p> |
| the hostname of the container. This is the value that should be supplied in the |
| <i>hostname</i> field of the <xref name="open"/> frame, and suring the SASL and |
| TLS negotiation (if used). |
| </p> |
| </dd> |
| <dt>network-host</dt> |
| <dd> |
| <p> |
| the DNS hostname or IP address of the machine hosting the container. |
| </p> |
| </dd> |
| <dt>port</dt> |
| <dd> |
| <p> |
| the port number on the machine hosting the container. |
| </p> |
| </dd> |
| </dl> |
| </doc> |
| </choice> |
| |
| </type> |
| |
| <type class="restricted" name="session-error" source="symbol" provides="error-condition" |
| label="symbols used to indicate session error conditions"> |
| |
| <choice name="window-violation" value="amqp:session:window-violation"> |
| <doc> |
| <p> |
| The peer violated incoming window for the session. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="errant-link" value="amqp:session:errant-link"> |
| <doc> |
| <p> |
| Input was received for a link that was detached with an error. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="handle-in-use" value="amqp:session:handle-in-use"> |
| <doc> |
| <p> |
| An attach was received using a handle that is already in use for an attached Link. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="unattached-handle" value="amqp:session:unattached-handle"> |
| <doc> |
| <p> |
| A frame (other than attach) was received referencing a handle which is not currently |
| in use of an attached Link. |
| </p> |
| </doc> |
| </choice> |
| </type> |
| |
| <type class="restricted" name="link-error" source="symbol" provides="error-condition" |
| label="symbols used to indicate link error conditions"> |
| |
| <choice name="detach-forced" value="amqp:link:detach-forced"> |
| <doc> |
| <p> |
| An operator intervened to detach for some reason. |
| </p> |
| </doc> |
| </choice> |
| |
| <choice name="transfer-limit-exceeded" value="amqp:link:transfer-limit-exceeded"> |
| <doc> |
| <p>The peer sent more Message transfers than currently allowed on the link.</p> |
| </doc> |
| </choice> |
| |
| <choice name="message-size-exceeded" value="amqp:link:message-size-exceeded"> |
| <doc> |
| <p>The peer sent a larger message than is supported on the link.</p> |
| </doc> |
| </choice> |
| |
| <choice name="redirect" value="amqp:link:redirect"> |
| <doc> |
| <p>The address provided cannot be resolved to a terminus at the current container. |
| The info map may contain the following information to allow the client to locate |
| the attach to the terminus. |
| </p> |
| <dl> |
| <dt>hostname</dt> |
| <dd> |
| <p> |
| the hostname of the container hosting the terminus. This is the value that should |
| be supplied in the <i>hostname</i> field of the <xref name="open"/> frame, and |
| during SASL and TLS negotiation (if used). |
| </p> |
| </dd> |
| <dt>network-host</dt> |
| <dd> |
| <p> |
| the DNS hostname or IP address of the machine hosting the container. |
| </p> |
| </dd> |
| <dt>port</dt> |
| <dd> |
| <p> |
| the port number on the machine hosting the container. |
| </p> |
| </dd> |
| <dt>address</dt> |
| <dd> |
| <p> |
| the address of the terminus at the container. |
| </p> |
| </dd> |
| </dl> |
| </doc> |
| </choice> |
| |
| <choice name="stolen" value="amqp:link:stolen"> |
| <doc> |
| <p> |
| The link has been attached elsewhere, causing the existing attachment to be forcibly |
| closed. |
| </p> |
| </doc> |
| </choice> |
| |
| </type> |
| |
| <definition name="PORT" value="5672" label="the IANA assigned port number for AMQP"> |
| <doc> |
| <p> |
| The standard AMQP port number that has been assigned by IANA for TCP, UDP, and SCTP. |
| </p> |
| </doc> |
| |
| <doc> |
| <p> |
| There are currently no UDP or SCTP mappings defined for AMQP. The port number is reserved |
| for future transport mappings to these protocols. |
| </p> |
| </doc> |
| </definition> |
| |
| <definition name="SECURE-PORT" value="5671" label="the IANA assigned port number |
| for secure AMQP (amqps)"> |
| <doc> |
| <p> |
| The standard AMQP port number that has been assigned by IANA for secure TCP using TLS. |
| </p> |
| </doc> |
| |
| <doc> |
| <p> |
| Implementations listening on this port should NOT expect a protocol handshake before TLS |
| is negotiated. |
| </p> |
| </doc> |
| </definition> |
| |
| <definition name="MAJOR" value="1" label="major protocol version" /> |
| <definition name="MINOR" value="0" label="minor protocol version" /> |
| <definition name="REVISION" value="0" label="protocol revision" /> |
| |
| <definition name="MIN-MAX-FRAME-SIZE" value="512" |
| label="the lower bound for the agreed maximum frame size (in bytes)"> |
| <doc> |
| <p> |
| During the initial Connection negotiation, the two peers must agree upon a maximum frame |
| size. This constant defines the minimum value to which the maximum frame size can be set. |
| By defining this value, the peers can guarantee that they can send frames of up to this |
| size until they have agreed a definitive maximum frame size for that |
| Connection. |
| </p> |
| </doc> |
| </definition> |
| </section> |
| |
| </amqp> |