OASIS AMQP Version 1.0
Part 2 : Transport

Committee Specification Draft 02

29 May 2012

Specification URIs

This version:

http://docs.oasis-open.org/amqp/core/v1.0/csd02/amqp-core-transport-v1.0-csd02.xml (Authoritative)

http://docs.oasis-open.org/amqp/core/v1.0/csd02/amqp-core-transport-v1.0-csd02.html

http://docs.oasis-open.org/amqp/core/v1.0/csd02/amqp-core-complete-v1.0-csd02.pdf

Previous version:

http://docs.oasis-open.org/amqp/core/v1.0/csd01/amqp-core-transport-v1.0-csd01.xml (Authoritative)

http://docs.oasis-open.org/amqp/core/v1.0/csd01/amqp-core-transport-v1.0-csd01.html

http://docs.oasis-open.org/amqp/core/v1.0/csd01/amqp-core-complete-v1.0-csd01.pdf

Latest version:

http://docs.oasis-open.org/amqp/core/v1.0/amqp-core-transport-v1.0.xml (Authoritative)

http://docs.oasis-open.org/amqp/core/v1.0/amqp-core-transport-v1.0.html

http://docs.oasis-open.org/amqp/core/v1.0/amqp-core-complete-v1.0.pdf

Technical Committee:

OASIS AMQP Technical Committee

Chairs:

Ram Jeyaraman (Ram.Jeyaraman@microsoft.com), Microsoft

Angus Telfer (angus.telfer@inetco.com), INETCO Systems

Editors:

Robert Godfrey (robert.godfrey@jpmorgan.com), JPMorgan Chase & Co.

David Ingham (David.Ingham@microsoft.com), Microsoft

Rafael Schloming (rafaels@redhat.com), Red Hat

Additional artifacts:

This specification consists of the following documents:

·        Part 0: Overview - Overview of the AMQP specification

·        Part 1: Types - AMQP type system and encoding

·        Part 2: Transport (this document) - AMQP transport layer

·        Part 3: Messaging - AMQP Messaging Layer

·        Part 4: Transactions - AMQP Transactions Layer

·        Part 5: Security - AMQP Security Layers

·        XML Document Type Definition (DTD)

Related work:

This specification replaces or supersedes:

·        http://www.amqp.org/specification/1.0/amqp-org-download

Abstract:

The Advanced Message Queuing Protocol (AMQP) is an open internet protocol for business messaging. It defines a binary wire-level protocol that allows for the reliable exchange of business messages between two parties. AMQP has a layered architecture and the specification is organized as a set of parts that reflects that architecture. Part 1 defines the AMQP type system and encoding. Part 2 defines the AMQP transport layer, an efficient, binary, peer-to-peer protocol for transporting messages between two processes over a network. Part 3 defines the AMQP message format, with a concrete encoding. Part 4 defines how interactions can be grouped within atomic transactions. Part 5 defines the AMQP security layers.

Status:

This document was last revised or approved by the OASIS AMQP Technical Committee on the above date. The level of approval is also listed above. Check the “Latest version” location noted above for possible later revisions of this document.

Technical Committee members should send comments on this specification to the Technical Committee’s email list. Others should send comments to the Technical Committee by using the "Send A Comment" button on the Technical Committee's web page at http://www.oasis-open.org/committees/amqp/.

For information on whether any patents have been disclosed that may be essential to implementing this specification, and any offers of patent licensing terms, please refer to the Intellectual Property Rights section of the Technical Committee web page (http://www.oasis-open.org/committees/amqp/ipr.php).

Citation format:

When referencing this specification the following citation format should be used:

[amqp-core-transport-v1.0]

OASIS AMQP Version 1.0 Part 2 : Transport. 29 May 2012. Committee Specification Draft 02. http://docs.oasis-open.org/amqp/core/v1.0/csd02/amqp-core-transport-v1.0-csd02.html.


Notices

Copyright OASIS Open 2012. All Rights Reserved.

All capitalized terms in the following text have the meanings assigned to them in the OASIS Intellectual Property Rights Policy (the "OASIS IPR Policy"). The full Policy may be found at the OASIS website.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published, and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this section are included on all such copies and derivative works. However, this document itself may not be modified in any way, including by removing the copyright notice or references to OASIS, except as needed for the purpose of developing any document or deliverable produced by an OASIS Technical Committee (in which case the rules applicable to copyrights, as set forth in the OASIS IPR Policy, must be followed) or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

OASIS requests that any OASIS Party or any other party that believes it has patent claims that would necessarily be infringed by implementations of this OASIS Committee Specification or OASIS Standard, to notify OASIS TC Administrator and provide an indication of its willingness to grant patent licenses to such patent claims in a manner consistent with the IPR Mode of the OASIS Technical Committee that produced this specification.

OASIS invites any party to contact the OASIS TC Administrator if it is aware of a claim of ownership of any patent claims that would necessarily be infringed by implementations of this specification by a patent holder that is not willing to provide a license to such patent claims in a manner consistent with the IPR Mode of the OASIS Technical Committee that produced this specification. OASIS may include such claims on its website, but disclaims any obligation to do so.

OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS' procedures with respect to rights in any document or deliverable produced by an OASIS Technical Committee can be found on the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this OASIS Committee Specification or OASIS Standard, can be obtained from the OASIS TC Administrator. OASIS makes no representation that any information or list of intellectual property rights will at any time be complete, or that any claims in such list are, in fact, Essential Claims.

The name "OASIS" is a trademark of OASIS, the owner and developer of this specification, and should be used only to refer to the organization and its official outputs. OASIS welcomes reference to, and implementation and use of, specifications, while reserving the right to enforce its marks against misleading uses. Please see http://www.oasis-open.org/who/trademark.php for above guidance.


Table of Contents



2.1 Transport
      2.1.1 conceptual model
      2.1.2 communication endpoints
      2.1.3 protocol frames
2.2 Version Negotiation
2.3 Framing
      2.3.1 Frame Layout
      2.3.2 AMQP Frames
2.4 Connections
      2.4.1 Opening a Connection
      2.4.2 Pipelined Open
      2.4.3 Closing a Connection
      2.4.4 Simultaneous Close
      2.4.5 Idle Timeout of a Connection
      2.4.6 Connection States
      2.4.7 Connection State Diagram
2.5 Sessions
      2.5.1 Establishing a Session
      2.5.2 Ending a Session
      2.5.3 Simultaneous End
      2.5.4 Session Errors
      2.5.5 Session States
      2.5.6 Session Flow Control
2.6 Links
      2.6.1 Naming a Link
      2.6.2 Link Handles
      2.6.3 Establishing or Resuming a Link
      2.6.4 Detaching and Reattaching a Link
      2.6.5 Link Errors
      2.6.6 Closing a Link
      2.6.7 Flow Control
      2.6.8 Synchronous Get
      2.6.9 Asynchronous Notification
      2.6.10 Stopping a Link
      2.6.11 Messages
      2.6.12 Transferring a Message
      2.6.13 Resuming Deliveries
      2.6.14 Transferring Large Messages
2.7 Performatives
      2.7.1 Open
      2.7.2 Begin
      2.7.3 Attach
      2.7.4 Flow
      2.7.5 Transfer
      2.7.6 Disposition
      2.7.7 Detach
      2.7.8 End
      2.7.9 Close
2.8 Definitions
      2.8.1 Role
      2.8.2 Sender Settle Mode
      2.8.3 Receiver Settle Mode
      2.8.4 Handle
      2.8.5 Seconds
      2.8.6 Milliseconds
      2.8.7 Delivery Tag
      2.8.8 Delivery Number
      2.8.9 Transfer Number
      2.8.10 Sequence No
      2.8.11 Message Format
      2.8.12 Ietf Language Tag
      2.8.13 Fields
      2.8.14 Error
      2.8.15 Amqp Error
      2.8.16 Connection Error
      2.8.17 Session Error
      2.8.18 Link Error
      2.8.19 Constant Definitions

2.1 Transport

2.1.1 Conceptual Model

An AMQP network consists of nodes connected via links. Nodes are named entities responsible for the safe storage and/or delivery of messages. Messages can originate from, terminate at, or be relayed by nodes.

A link is a unidirectional route between two nodes. A link attaches to a node at a terminus. There are two kinds of terminus: sources and targets. 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 only travel along a link if they meet the entry criteria at the source.

As a message travels through an AMQP network, the responsibility for safe storage and delivery of the message is transferred between the nodes it encounters. The link protocol (defined in section 2.6) manages the transfer of responsibility between the source and target.

Figure 2.1: Message Transfer between Nodes
+------------+ +------------+ / 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

Nodes exist within a container. Examples of containers are brokers and client applications. Each container MAY hold many nodes. Examples of AMQP nodes are producers, consumers, and queues. Producers and consumers are the elements within an application that generate and process messages. Queues are entities that store and forward messages.

Figure 2.2: Class Diagram of Concrete Containers and Nodes
+---------------+ +----------+ | <<Container>> | 1..1 0..n | <<Node>> | |---------------|<>-------------------->|----------| | container-id | | name | +---------------+ +----------+ /_\ /_\ | | | | +-----+-----+ +----------+----------+ | | | | | | | | | | +--------+ +--------+ +----------+ +----------+ +-------+ | Broker | | Client | | Producer | | Consumer | | Queue | |--------| |--------| |----------| |----------| |-------| | | | | | | | | | | +--------+ +--------+ +----------+ +----------+ +-------+

2.1.2 Communication Endpoints

The AMQP transport specification defines a peer-to-peer protocol for transferring messages between nodes in an 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.

In order for communication to occur between nodes in different containers a connection needs be established.

Figure 2.3: An AMQP Connection
Client App Broker +-------------+ +-------------+ | |################################| | | +---+ | | +---+ | | | C | | Connection | | Q | | | +-+-+ | | +-+-+ | | | |################################| | | +-----|-------+ +------|------+ | | Consumer Queue (Node) (Node)

An AMQP connection consists of a full-duplex, reliably ordered sequence of frames. 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 section 2.7. The precise requirement for a connection is that if the nth frame arrives, all frames prior to n MUST also have arrived. It is assumed connections are transient and can 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 section 2.3).

An AMQP connection is divided into a negotiated number of independent unidirectional channels. 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.

An AMQP session correlates two unidirectional channels to form a bidirectional, sequential conversation between two containers. Sessions provide a flow control scheme based on the number of transfer frames transmitted. Since frames have a maximum size for a given connection, this provides flow control based on the number of bytes transmitted and can be used to optimize performance.

Figure 2.4: An AMQP Session
Client App Broker +-------------+ +-------------+ | |################################| | | +---+ |--------------------------------| +---+ | | | C | | Session | | Q | | | +---+ |--------------------------------| +---+ | | |################################| | +-------------+ +-------------+

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 endpoints that store local and last known remote state regarding the connection or session in question.

Figure 2.5: Session & Connection Endpoints
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

In order to transfer messages between nodes (e.g., to move messages from a queue to a consumer) a link needs to be established between the nodes. A link is a unidirectional route between two nodes. A link attaches to a node at a terminus. There are two kinds of terminus: sources and targets. 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 only travel along a link if they meet the entry criteria at the source.

Links provide a credit-based flow control scheme based on the number of messages transmitted, allowing applications to control which nodes to receive messages from at a given point (e.g., to explicitly fetch a message from a given queue).

Figure 2.6: An AMQP Link
Client App Broker +-------------+ +-------------+ | |################################| | | +---+ |--------------------------------| +---+ | | | C |O<=================+======================O| Q | | | +---+ \ |-------------|------------------| |+---+ | | \ |#############|##################| | | +-----------\-+ | +---|---------+ \ | | Target | Source Link

Sessions provide the context for communication between sources and targets. A link endpoint associates a terminus with a session endpoint. Within a session, the link protocol (defined in section 2.6) is used to establish links between sources and targets and to transfer messages across them. A single session can be simultaneously associated with any number of links.

Links are named, and the state at the termini can live longer than the connection on which they were established.

Figure 2.7: Connection Loss
Client App Broker +-------------+ +-------------+ | | | | | +---+ | | +---+ | | | C |O<=| | | |=O| Q | | | +---+| | | |+---+ | | | | | | | +--------|----+ +---|---------+ | | | | State retained State retained at Target at Source

The retained state at the termini can be used to reestablish the link on a new connection (and session) with precise control over delivery guarantees (e.g., ensuring "exactly once" delivery).

Figure 2.8: Link Recovery
Client App Broker +-------------+ +-------------+ | |################################| | | +---+ |--------------------------------| +---+ | | | C |O<========================================O| Q | | | +---+ |--------------------------------| +---+ | | |################################| | +-------------+ +-------------+

The diagram below shows the relationship between the three AMQP communication endpoints, Connection, Session and Link.

Figure 2.9: Class Diagram of Communication Endpoints
+-------------+ | 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 | +------------+

2.1.3 Protocol Frames

The protocol consists of nine frame body types that are formally defined in section 2.7. The following table lists the frame bodies and defines which endpoints handle them.

Figure 2.10: Frame Dispatch Table
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)

2.2 Version Negotiation

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 1 (MAJOR), 0 (MINOR), 0 (REVISION)). In total this is an 8-octet sequence:

Figure 2.11: Protocol Header Layout
4 OCTETS 1 OCTET 1 OCTET 1 OCTET 1 OCTET +----------+---------+---------+---------+----------+ | "AMQP" | %d0 | major | minor | revision | +----------+---------+---------+---------+----------+

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.

The AMQP peer which acted in the role of the TCP client (i.e. the peer that actively opened the connection) MUST immediately send its outgoing protocol header on establishment of the TCP connection. 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. This permits a multi protocol server implementation to choose the correct protocol version to fit each client.

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):

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.

Figure 2.12: Version Negotiation Examples
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

Please note that the above examples use the literal notation defined in RFC 2234 [RFC2234] for non alphanumeric values.

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 section 5.1). In this case, the server MUST send a protocol header with an acceptable protocol id (and version) and then close the socket. It MAY choose any protocol id.

Figure 2.13: Protocol ID Rejection Example
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

2.3 Framing

Frames are divided into three distinct areas: a fixed width frame header, a variable width extended header, and a variable width frame body.

Figure 2.14: Frame Layout
REQUIRED OPTIONAL OPTIONAL +--------------+-----------------+------------+ | frame header | extended header | frame body | +--------------+-----------------+------------+ 8 bytes *variable* *variable*
frame header

The frame header is a fixed size (8 byte) structure that precedes each frame. The frame header includes mandatory information necessary to parse the rest of the frame including size and type information.

extended header

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.

frame body

The frame body is a variable width sequence of bytes the format of which depends on the frame type.

2.3.1 Frame Layout

The diagram below shows the details of the general frame layout for all frame types.

Figure 2.15: General Frame Layout
+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 . . | . . | . ________| | | ... | | +--------------------------+ -'
SIZE

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 frame header (8 bytes).

DOFF

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 an 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.

TYPE

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 section 5.3.

2.3.2 AMQP Frames

Bytes 6 and 7 of an AMQP frame contain the channel number (see section 2.1). The frame body is defined as a performative followed by an opaque payload. The performative MUST be one of those defined in section 2.7 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.

Figure 2.16: AMQP Frame Layout
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 . | . . | . ________| | | ... | | +--------------------------+ -'

An AMQP frame with no body MAY be used to generate artificial traffic as needed to satisfy any negotiated idle timeout interval (see subsection 2.4.5).

2.4 Connections

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 open and 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.

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.

Figure 2.17: Unidirectional Channel Multiplexing
+-------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

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.

Figure 2.18: Bidirectional Channel Multiplexing
+-------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

Although not strictly directed at the connection endpoint, the begin and end frames are potentially 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 section 2.5).

2.4.1 Opening A Connection

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 512 (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 open frame before sending any other frames. The open frame describes the capabilities and limits of that peer. The open frame can only be sent on channel 0. After sending the open frame and reading its partner's open frame a peer MUST operate within mutually acceptable limitations from this point forward.

Figure 2.19: Synchronous Connection Open Sequence
TCP Client TCP Server ================================== TCP-CONNECT TCP-ACCEPT PROTO-HDR PROTO-HDR OPEN ---+ +--- OPEN \ / wait x wait / \ proceed <--+ +--> proceed ...

2.4.2 Pipelined Open

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 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 can 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 open frame.

Figure 2.20: Pipelined Connection Open Sequence
TCP Client TCP Server ============================================= TCP-CONNECT TCP-ACCEPT PROTO-HDR PROTO-HDR OPEN ---+ +--- OPEN \ / pipelined frame x pipelined frame / \ proceed <--+ +--> proceed ... ---------------------------------------------

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.

2.4.3 Closing A Connection

Prior to closing a connection, each peer MUST write a 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 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 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 open.

Figure 2.21: Synchronous Connection Close Sequence
TCP Client TCP Server ============================= ... CLOSE -------> +-- CLOSE / TCP-CLOSE TCP-CLOSE <--+

Implementations SHOULD NOT expect to be able to reuse open TCP sockets after close performatives have been exchanged. There is no requirement for an implementation to read from a socket after a close performative has been received.

2.4.4 Simultaneous Close

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.

Figure 2.22: Simultaneous Connection Close Sequence
TCP Client TCP Server ================================ ... CLOSE ---+ +--- CLOSE \ / x / \ TCP-CLOSE <--+ +--> TCP-CLOSE

2.4.5 Idle Timeout Of A Connection

Connections are subject to an idle timeout threshold. The timeout is triggered by a local peer when no frames are received after a threshold value is exceeded. The idle timeout 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 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.

Each peer has its own (independent) idle timeout. At connection open each peer communicates the maximum period between activity (frames) on the connection that it desires from its partner.The open frame carries the idle-time-out field for this purpose. To avoid spurious timeouts, the value in idle-time-out SHOULD be half the peer's actual timeout threshold.

If a peer can not, for any reason support a proposed idle timeout, then it SHOULD close the connection using a close frame with an error explaining why. There is no requirement for peers to support arbitrarily short or long idle timeouts.

The use of idle timeouts is in addition to any network protocol level control. Implementations SHOULD make use of TCP keep-alive wherever possible in order to be good citizens.

If a peer needs to satisfy the need to send traffic to prevent idle timeout, 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. Implementations MUST be prepared to handle empty frames arriving on any valid channel, though implementations SHOULD use channel 0 when sending empty frames, and MUST use channel 0 if a maximum channel number has not yet been negotiated (i.e., before an open frame has been received). Apart from this use, empty frames have no meaning.

Empty frames can only be sent after the open frame is sent. As they are a frame, they MUST NOT be sent after the close frame has been sent.

As an alternative to using an empty frame to prevent an idle timeout, if a connection is in a permissible state, an implementation MAY choose to send a flow frame for a valid session.

If during operation a peer exceeds the remote peer's idle timeout's threshold, e.g., because it is heavily loaded, it SHOULD gracefully close the connection by using a close frame with an error explaining why.

2.4.6 Connection States

START

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.

HDR_RCVD

In this state the connection header has been received from the peer but a connection header has not been sent.

HDR_SENT

In this state the connection header has been sent to the peer but no connection header has been received.

HDR_EXCH

In this state the connection header has been sent to the peer and a connection header has been received from the peer.

OPEN_PIPE

In this state both the connection header and the open frame have been sent but nothing has been received.

OC_PIPE

In this state, the connection header, the open frame, any pipelined connection traffic, and the close frame have been sent but nothing has been received.

OPEN_RCVD

In this state the connection headers have been exchanged. An open frame has been received from the peer but an open frame has not been sent.

OPEN_SENT

In this state the connection headers have been exchanged. An open frame has been sent to the peer but no open frame has yet been received.

CLOSE_PIPE

In this state the connection headers have been exchanged. An open frame, any pipelined connection traffic, and the close frame have been sent but no open frame has yet been received from the peer.

OPENED

In this state the connection header and the open frame have been both sent and received.

CLOSE_RCVD

In this state a close frame has been received indicating that the peer has initiated an AMQP close. No further frames are expected to arrive on the connection; however, frames can still be sent. If desired, an implementation MAY do a TCP half-close at this point to shut down the read side of the connection.

CLOSE_SENT

In this state a close frame has been sent to the peer. It is illegal to write anything more onto the connection, however there could potentially still be incoming frames. If desired, an implementation MAY do a TCP half-close at this point to shutdown the write side of the connection.

DISCARDING

The DISCARDING state is a variant of the CLOSE_SENT state where the close is triggered by an error. In this case any incoming frames on the connection MUST be silently discarded until the peer's close frame is received.

END

In this state it is illegal for either endpoint to write anything more onto the connection. The connection can be safely closed and discarded.

2.4.7 Connection State Diagram

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.

Figure 2.23: Connection State Diagram
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
Figure 2.24: Connection State Table
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

2.5 Sessions

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 attached to a given session. However, a link MUST NOT be attached to more than one session at a time.

Figure 2.25: Instance Diagram of Session/Link attachment
Link A-------+ +------>Link A | | \|/ (attached) | Link B<--- Session <--------------> Session <---Link B Link C------>* (detached) *------>Link C

Messages transferred on a link are sequentially identified within the session. A session can 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 aggregation of otherwise independent links into a single stream that can be efficiently acknowledged by the receiving application.

2.5.1 Establishing A Session

Sessions are established by creating a session endpoint, assigning it to an unused channel number, and sending a begin announcing the association of the session endpoint with the outgoing channel. Upon receiving the 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 begin setting the remote-channel field to the incoming channel of the remotely initiated session.

To make it easier to monitor AMQP sessions, it is RECOMMENDED that implementations always assign the lowest available unused channel number.

The remote-channel field of a 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.

Figure 2.26: Session Begin Sequence
Endpoint Endpoint ===================================================================== [CH3] BEGIN(name=..., ---------> remote-channel=null) +-- [CH7] BEGIN(name=..., / remote-channel=3) / <---+ ... ---------------------------------------------------------------------

2.5.2 Ending A Session

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 end frame is sent to announce the disassociation of the endpoint from its outgoing channel, and to carry error information when relevant.

Figure 2.27: Session End Sequence
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.

2.5.3 Simultaneous End

Due to the potentially asynchronous nature of sessions, it is possible that both peers simultaneously decide to end a session. If this happens, it will appear to each peer as though their partner's spontaneously initiated end frame is actually an answer to the peers initial end frame.

Figure 2.28: Simultaneous Session End Sequence
Endpoint A Endpoint B ================================================================= ... [CH3] END(error=...) --+ +-- [CH7] END(error=...) (1) \ / (2) x / \ (3) <-+ +-> (4) ... ----------------------------------------------------------------- (1) At this point no more frames can be sent by A. (2) At this point no more frames can be sent by B. (3) At this point endpoint A is fully ended. (4) At this point endpoint B is fully ended.

2.5.4 Session Errors

When a session is unable to process input, it MUST indicate this by issuing an END with an appropriate error indicating the cause of the problem. It MUST then proceed to discard all incoming frames from the remote endpoint until receiving the remote endpoint's corresponding end frame.

Figure 2.29: Session Error Sequence
Endpoint Endpoint ================================================ FRAME 1 ----------> FRAME 2 ----------> FRAME 3 ---+ +--- END(error=...) \ / x / \ <--+ +--> *discarded* END ----------> ... ================================================

2.5.5 Session States

UNMAPPED

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.

BEGIN_SENT

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.

BEGIN_RCVD

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.

MAPPED

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.

END_SENT

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.

END_RCVD

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.

DISCARDING

The DISCARDING state is a variant of the END_SENT state where the end is triggered by an error. In this case any incoming frames on the session MUST be silently discarded until the peer's end frame is received.

Figure 2.30: State Transitions
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 | +-------------+-------------+ | | | | | +------------------------+

There is no obligation to retain a session endpoint after it transitions to the UNMAPPED state.

2.5.6 Session Flow Control

The session endpoint assigns each outgoing transfer frame an implicit transfer-id from a session scoped sequence. Each session endpoint maintains the following state to manage incoming and outgoing transfer frames:

next-incoming-id

The next-incoming-id identifies the expected transfer-id of the next incoming transfer frame.

incoming-window

The incoming-window defines the maximum number of incoming 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 incoming-window and next-incoming-id.

next-outgoing-id

The next-outgoing-id is the transfer-id to assign to the next transfer frame. The next-outgoing-id MAY be initialized to an arbitrary value and is incremented after each successive transfer according to RFC-1982 [RFC1982] serial number arithmetic.

outgoing-window

The outgoing-window defines the maximum number of outgoing 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 outgoing-window and next-outgoing-id.

remote-incoming-window

The remote-incoming-window 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 transfer frame is sent, and recomputed when informed of the remote session endpoint state.

remote-outgoing-window

The remote-outgoing-window 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 transfer frame is received, and recomputed when informed of the remote session endpoint state. When this window shrinks, it is an indication of outstanding transfers. Settling outstanding transfers can cause the window to grow.

Once initialized, this state is updated by various events that occur in the lifespan of a session and its associated links:

sending a transfer

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.

receiving a transfer

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.

receiving a flow

When the endpoint receives a flow frame from its peer, it MUST update the next-incoming-id directly from the next-outgoing-id of the frame, and it MUST update the remote-outgoing-window directly from the outgoing-window of the frame.

The remote-incoming-window is computed as follows:

next-incoming-idflow + incoming-windowflow - next-outgoing-idendpoint

If the next-incoming-id field of the flow frame is not set, then remote-incoming-window is computed as follows:

initial-outgoing-idendpoint + incoming-windowflow - next-outgoing-idendpoint

2.6 Links

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 unsettled deliveries. When a terminus forgets the state associated with a delivery-tag, it is considered settled. Settling a delivery at a terminus is an idempotent idempotent, i.e., a delivery can transition from unsettled to settled, but never the reverse. Each delivery attempt is assigned a unique delivery-tag at the source. The status of an active delivery attempt is known as the delivery state of the delivery.

Link endpoints interface between a terminus and a session endpoint, and maintain additional state used for active communication between the local and remote endpoints. Therefore there are two types of endpoint: senders and receivers. 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 delivery-id from a session scoped sequence. These delivery-ids are used to efficiently reference subsets of the outstanding deliveries on a session.

Termini can 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 suspended 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 resuming a link.

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.

2.6.1 Naming A Link

Links are named so that they can 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 can be arbitrarily long without a significant penalty.

A link's name uniquely identifies the link from the container of the source to the container of the target node, i.e., if the container of the source node is A, and the container of the target node is B, the link can be globally identified by the (ordered) tuple (A,B,<name>). Consequently, a link can 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 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.

2.6.2 Link Handles

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 (attach, detach, flow, transfer, disposition). This handle is assigned by the initial 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 output handle. The remotely chosen handle is referred to as the input handle.

At an endpoint, a link is considered to be attached when the link endpoint exists and has both input and output handles assigned at an active session endpoint. A link is considered to be detached when the link endpoint exists, but is not assigned either input or output handles. A link can be considered half attached (or half detached) when only one of the input or output handles is assigned.

Figure 2.31: Link Handles
+-------------------+ +-------------------+ | 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 | +-------------------+ +-------------------+

2.6.3 Establishing Or Resuming A Link

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 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 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 can 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 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 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.

Figure 2.32: Establishing a Link
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) <--+ ... ----------------------------------------------------------------

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.

Figure 2.33: Refusing a Link
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.

If either end of the link is already associated with a terminus, the attach frame MUST include its unsettled delivery state.

Figure 2.34: Resuming a Link
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.

Note that it is possible that the expected terminus properties do not 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.

When a link is established, it is possible for an endpoint not to have all the capabilities necessary to create the terminus exactly matching the expectations of the peer. If this happens, 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.

When resuming a link, it is possible that the properties of the source and target have changed while the link was suspended. When this happens, the termini properties communicated in the source and target fields of the attach frames could 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, detach the link.

Note that a peer MUST take responsibility for verifying that the remote terminus meets its requirements. The remote peer SHOULD NOT attempt to preempt whether the terminus will meet the requirements of its partner. This is equally true both for creating and resuming links.

Figure 2.35: Resuming an altered Link
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.

It is possible to resume a link even if one of the termini has lost nearly all its state. All that is necessary is the link name and direction. This is referred to as recovering 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 attach frame will be null.

Figure 2.36: Recovering a Link
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.

2.6.4 Detaching And Reattaching A Link

A session endpoint can choose to unmap its output handle for a link. In this case, the endpoint MUST send a detach frame to inform the remote peer that the handle is no longer attached to the link endpoint. If 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 could still be active deliveries on the link referenced via delivery-id.

Figure 2.37: Detaching a Link
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.

When the state of a link endpoint changes, this is can be communicated by detaching and then reattaching with the updated state on the attach frame. This can be used to update the properties of the link endpoints, or to update the properties of the termini.

Figure 2.38: Updating Link State
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.

2.6.5 Link Errors

When an error occurs at a link endpoint, the endpoint MUST be detached with appropriate error information supplied in the error field of the detach frame. The link endpoint MUST then be destroyed. If 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 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 attach performative MUST contain a non-null value for its unsettled field. Receipt of a pipelined attach MUST result in the session being terminated with an errant-link session-error.

2.6.6 Closing A Link

A peer closes a link by sending the 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 detach frame with the closed flag set to true.

Figure 2.39: Closing a Link
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.

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.

2.6.7 Flow Control

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 occur, such as insufficient messages to consume the currently available link-credit, or insufficient link-credit to send available messages:

delivery-count

The delivery-count is initialized by the sender when a link endpoint is created, and is incremented whenever a message is sent. 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. Note that, despite its name, the delivery-count is not a count but a sequence number initialized at an arbitrary point by the sender.

link-credit

The link-credit variable defines the current maximum legal amount that the delivery-count can be increased by. This identifies a delivery-limit that can be computed by adding the link-credit to the delivery-count.

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 delivery-limit 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:

link-creditsnd := delivery-countrcv + link-creditrcv - delivery-countsnd.

In the event that the receiver does not yet know the delivery-count, i.e., delivery-countrcv is unspecified, the sender MUST assume that the delivery-countrcv is the first delivery-countsnd sent from sender to receiver, i.e., the delivery-countsnd specified in the flow state carried by the initial attach frame from the sender to the receiver.

Additionally, whenever the sender increases delivery-count, it MUST decrease link-credit by the same amount in order to maintain the delivery-limit identified by the receiver.

available

The available variable is controlled by the sender, and indicates to the receiver, that the sender could make use of the indicated amount of link-credit. 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. If this happens, the receiver MUST maintain a floor of zero in its calculation of the value of available.

drain

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.

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, a sender MUST NOT 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.

Figure 2.40: Flow Control
+----------+ +----------+ | Sender |---------------transfer------------>| Receiver | +----------+ +----------+ \ / <----------------flow--------------- \ / +------+ +------+ | | | if link-credit <= 0 then pause

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 flow state to the receiver.

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 [RFC1982] serial number arithmetic.

The initial flow state of a link endpoint is determined as follows. The link-credit and available variables are initialized to zero. The drain flag is initialized to false. The sender MAY choose an arbitrary point to initialize the delivery-count. This value is communicated in the initial attach frame. The receiver initializes its delivery-count upon receiving the sender's attach.

Figure 2.41: Flow State & related Frames
flow state | | modifies +------------------+ | +------------------+ | Sender | .----------------------. | Receiver | +------------------+ attach, transfer, flow +------------------+ | delivery-count |------------------------------->| delivery-count | | link-credit | | link-credit | | available |<-------------------------------| available | | drain | flow | drain | +------------------+ '-----' +------------------+ | | modifies | flow state

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.

Figure 2.42: Flow Control Usage Patterns
+----------+ +----------+ | 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, ...) ---->

2.6.8 Synchronous Get

A synchronous get of a message from a link is accomplished by incrementing the link-credit, sending the updated flow state, and waiting indefinitely for a transfer to arrive.

Figure 2.43: Synchronous Get
Receiver Sender ================================================================= ... flow(link-credit=1) ----------> +---- transfer(...) *block until transfer arrives* / <---+ ... -----------------------------------------------------------------

Synchronous get with a timeout is accomplished by incrementing the link-credit, sending the updated 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 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.

Figure 2.44: Synchronous Get w/ Timeout
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.

2.6.9 Asynchronous Notification

Asynchronous notification can be accomplished as follows. The receiver maintains a target amount of link-credit for that link. As transfers 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 flow state MAY be sent to increase the sender's link-credit back to the desired target amount.

Figure 2.45: Asynchrnous Notification
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.

2.6.10 Stopping A Link

Stopping the transfers on a given link is accomplished by updating the link-credit to be zero and sending the updated flow state. It is possible that some transfers could be in flight at the time the flow state is sent, so incoming transfers could still arrive on the link. The echo field of the flow frame MAY be used to request the sender's flow state be echoed back. This MAY be used to determine when the link has finally quiesced.

Figure 2.46: Stopping Incoming Messages
Receiver Sender ================================================================ ... <---------- transfer(...) flow(..., ---+ +--- transfer(...) link-credit=0, \ / echo=True) x / \ (1) <--+ +--> (2) <---------- flow(...) ... ---------------------------------------------------------------- (1) In-flight transfers can still arrive until the flow state is updated at the sender. (2) At this point no further transfers will arrive.

2.6.11 Messages

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 transfer performative. Messages can be fragmented across several transfer frames as indicated by the more flag of the transfer performative.

2.6.12 Transferring A Message

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 unsettled at the sender/receiver from the point at which it was sent/received until it has been settled 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.

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, the delivery's 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.

The following diagrams illustrate the fundamentals involved in transferring a message. For normative semantics please refer to the definitions of the transfer and disposition performatives. 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.

Figure 2.47: Initial Transfer
+------------------+ / Sender \ +----------------------+ | unsettled: | transfer(delivery-tag=DT, settled=False, | ... | state=S_0, ...) | DT -> (local: S_0, |-----------------------------------------------> | remote: ?) | | ... | +----------------------+

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.

Figure 2.48: Initial Receipt
+------------------+ / Receiver \ +----------------------+ transfer(delivery-tag=DT, settled=False, | unsettled: | state=S_0, ...) | ... | ----------------------------------------------->| DT -> (local: S_1, | | remote: S_0)| | ... | +----------------------+

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 terminal or non-terminal 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 disposition frame.

Figure 2.49: Indication of Non-Terminal State
+------------------+ / Receiver \ +----------------------+ | unsettled: | | ... | <-----------------------------------------------| DT -> (local: S_2, | disp(role=receiver, ..., delivery-tag=DT, | remote: S_0)| settled=False, state=S_2, ...) | ... | +----------------------+

Once the receiving application has finished processing the message, it indicates to the link endpoint a terminal 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.

Figure 2.50: Indication of Presumptive Terminal State
+------------------+ / Receiver \ +----------------------+ | unsettled: | | ... | <-----------------------------------------------| DT -> (local: T_0, | disp(role=receiver, ..., delivery-tag=DT, | remote: S_0)| settled=False, state=T_0, ...) | ... | +----------------------+

Upon receiving the updated delivery state from the receiver, the sender will, if it has not already spontaneously attained a terminal state (e.g., through the expiry of the TTL at the sender), update its view of the state and communicate this back to the sending application.

Figure 2.51: Receipt of Terminal State
+------------------+ / Sender \ +----------------------+ | unsettled: | | ... | | DT -> (local: S_0, |<----------------------------------------------- | remote: T_0)| disp(role=receiver, ..., delivery-tag=DT, | ... | settled=False, state=T_0, ...) +----------------------+

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. If this frame gets 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 not 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).

Figure 2.52: Indication of Settlement
+------------------+ / Sender \ +----------------------+ | unsettled: | disp(role=sender, ..., delivery-tag=DT, | ... | settled=True, state=T_1, ...) | - -> - |-----------------------------------------------> | ... | +----------------------+

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.

Figure 2.53: Receipt of Settlement
+------------------+ / Receiver \ +----------------------+ disp(role=sender, ..., delivery-tag=DT, | unsettled: | settled=True, state=T_1, ...) | ... | ----------------------------------------------->| DT -> (local: S_2, | | remote: - ) | | ... | +----------------------+

The application can 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.

Figure 2.54: Final Settlement
+------------------+ / Receiver \ +----------------------+ | unsettled: | | ... | <-----------------------------------------------| - -> - | | ... | +----------------------+

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.

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.

This basic pattern can be modified in a variety of ways to achieve different guarantees. For example if the sending application settles the delivery before sending it, this results in an at-most-once 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. If this delivery makes 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.

Figure 2.55: At-Most-Once
+------------------+ / Sender \ +----------------------+ | unsettled: | transfer(delivery-tag=DT, settled=True, | ... | state=T_0, ...) | - -> - |-----------------------------------------------> | ... | +----------------------+

Similarly, if the basic scenario is modified such that the receiving application chooses to settle immediately upon processing the message rather than waiting for the sender to settle first, that yields an at-least-once 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.

Figure 2.56: At-Least-Once
+------------------+ / Receiver \ +----------------------+ | unsettled: | | ... | <-----------------------------------------------| - -> - | disp(role=receiver, ..., delivery-tag=DT, | ... | settled=True, state=T_0, ...) | | +----------------------+

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 exactly-once 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 the initial transmission. Similarly, if the sender settles before the receiver reaches a terminal state, it is possible for messages to be lost.

The sender and receiver policy regarding settling can either be preconfigured for the entire link, thereby allowing for optimized endpoint choices, or can 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.

2.6.13 Resuming Deliveries

When a suspended link having unsettled deliveries is resumed, the unsettled field from the 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:

Deliveries that only the source considers unsettled

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).

Deliveries that only the target considers unsettled

Deliveries in this category MUST be ignored by the sender, and MUST be considered settled by the receiver.

Deliveries that both the source and target consider unsettled

Deliveries in this category MUST be resumed by the sender.

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 can new unsettled state be created by the sending of non-resuming transfers.

A delivery is resumed much the same way it is initially transferred with the following exceptions:

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.

2.6.14 Transferring Large Messages

Each transfer frame can 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 transfer frames by setting the more flag on all but the last transfer frame. When a message is split up into multiple 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.

The sender MAY indicate an aborted attempt to deliver a message by setting the abort flag on the last transfer. In this case the receiver MUST discard the message data that was transferred prior to the abort.

Figure 2.57: Outgoing Fragmentation State Diagram
+------------+ 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=?)
Figure 2.58: Incoming Fragmentation State Diagram
+------------+ 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=?)

2.7 Performatives

2.7.1 Open

Negotiate connection parameters.

<type name="open" class="composite" source="list" provides="frame"> <descriptor name="amqp:open:list" code="0x00000000:0x00000010"/> <field name="container-id" type="string" mandatory="true"/> <field name="hostname" type="string"/> <field name="max-frame-size" type="uint" default="4294967295"/> <field name="channel-max" type="ushort" default="65535"/> <field name="idle-time-out" type="milliseconds"/> <field name="outgoing-locales" type="ietf-language-tag" multiple="true"/> <field name="incoming-locales" type="ietf-language-tag" multiple="true"/> <field name="offered-capabilities" type="symbol" multiple="true"/> <field name="desired-capabilities" type="symbol" multiple="true"/> <field name="properties" type="fields"/> </type>

The first frame sent on a connection in either direction MUST contain an open performative. 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.

container-idthe id of the source containermandatory string
hostnamethe name of the target hostoptional string

The 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.

This field MAY already have been specified by the 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 that already specified means.

max-frame-sizeproposed maximum frame sizeoptional uint

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.

Both peers MUST accept frames of up to 512 (MIN-MAX-FRAME-SIZE) octets.

channel-maxthe maximum channel number that can be used on the connectionoptional ushort

The channel-max value is the highest channel number that can 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.

idle-time-outidle time-outoptional milliseconds

The idle timeout REQUIRED by the sender (see subsection 2.4.5). 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 (e.g., because it is too small).

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.

outgoing-localeslocales available for outgoing textoptional ietf-language-tag[]

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 en-US locale (see subsection 2.8.12). 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 en-US is supported.

incoming-localesdesired locales for incoming text in decreasing level of preferenceoptional ietf-language-tag[]

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 choose the first (most preferred) incoming locale from those which it supports. If none of the requested locales are supported, en-US will be chosen. Note that en-US 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 en-US is supported.

offered-capabilitiesextension capabilities the sender supportsoptional symbol[]

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.

A registry of commonly defined connection capabilities and their meanings is maintained [AMQPCONNCAP].

desired-capabilitiesextension capabilities the sender can use if the receiver supports themoptional symbol[]

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). The sender MUST NOT attempt to use any capabilities it did not declare in the desired-capabilities field. If the receiver of the desired-capabilities offers extension capabilities which are not present in the desired-capabilities list it received, then it can be sure those (undesired) capabilities will not be used on the connection.

propertiesconnection propertiesoptional fields

The properties map contains a set of fields intended to indicate information about the connection and its container.

A registry of commonly defined connection properties and their meanings is maintained [AMQPCONNPROP].

2.7.2 Begin

Begin a session on a channel.

<type name="begin" class="composite" source="list" provides="frame"> <descriptor name="amqp:begin:list" code="0x00000000:0x00000011"/> <field name="remote-channel" type="ushort"/> <field name="next-outgoing-id" type="transfer-number" mandatory="true"/> <field name="incoming-window" type="uint" mandatory="true"/> <field name="outgoing-window" type="uint" mandatory="true"/> <field name="handle-max" type="handle" default="4294967295"/> <field name="offered-capabilities" type="symbol" multiple="true"/> <field name="desired-capabilities" type="symbol" multiple="true"/> <field name="properties" type="fields"/> </type>

Indicate that a session has begun on the channel.

remote-channelthe remote channel for this sessionoptional ushort

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.

next-outgoing-idthe transfer-id of the first transfer id the sender will sendmandatory transfer-number
incoming-windowthe initial incoming-window of the sendermandatory uint
outgoing-windowthe initial outgoing-window of the sendermandatory uint
handle-maxthe maximum handle value that can be used on the sessionoptional handle

The handle-max value is the highest handle value that can 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.

offered-capabilitiesthe extension capabilities the sender supportsoptional symbol[]

A registry of commonly defined session capabilities and their meanings is maintained [AMQPSESSCAP].

desired-capabilitiesthe extension capabilities the sender can use if the receiver supports themoptional symbol[]

The sender MUST NOT attempt to use any capability other than those it has declared in desired-capabilities field.

propertiessession propertiesoptional fields

The properties map contains a set of fields intended to indicate information about the session and its container.

A registry of commonly defined session properties and their meanings is maintained [AMQPSESSPROP].

2.7.3 Attach

Attach a link to a session.

<type name="attach" class="composite" source="list" provides="frame"> <descriptor name="amqp:attach:list" code="0x00000000:0x00000012"/> <field name="name" type="string" mandatory="true"/> <field name="handle" type="handle" mandatory="true"/> <field name="role" type="role" mandatory="true"/> <field name="snd-settle-mode" type="sender-settle-mode" default="mixed"/> <field name="rcv-settle-mode" type="receiver-settle-mode" default="first"/> <field name="source" type="*" requires="source"/> <field name="target" type="*" requires="target"/> <field name="unsettled" type="map"/> <field name="incomplete-unsettled" type="boolean" default="false"/> <field name="initial-delivery-count" type="sequence-no"/> <field name="max-message-size" type="ulong"/> <field name="offered-capabilities" type="symbol" multiple="true"/> <field name="desired-capabilities" type="symbol" multiple="true"/> <field name="properties" type="fields"/> </type>

The attach frame indicates that a link endpoint has been attached to the session.

namethe name of the linkmandatory string

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 (A,B,<name>).

handlethe handle for the link while attachedmandatory handle

The numeric handle assigned by the the peer as a shorthand to refer to the link in all performatives that reference the link until the it is detached. See subsection 2.6.2.

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 close carrying a handle-in-use session-error.

To make it easier to monitor AMQP link attach frames, it is RECOMMENDED that implementations always assign the lowest available handle to this field.

rolerole of the link endpointmandatory role

The role being played by the peer, i.e., whether the peer is the sender or the receiver of messages on the link.

snd-settle-modesettlement policy for the senderoptional sender-settle-mode

The delivery settlement policy for 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. The sender SHOULD respect the receiver's desired settlement mode if the receiver initiates the attach exchange and the sender supports the desired mode.

rcv-settle-modethe settlement policy of the receiveroptional receiver-settle-mode

The delivery settlement policy for 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. The receiver SHOULD respect the sender's desired settlement mode if the sender initiates the attach exchange and the receiver supports the desired mode.

sourcethe source for messagesoptional *

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.

targetthe target for messagesoptional *

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.

unsettledunsettled delivery stateoptional map

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 subsection 2.6.13.

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. The endpoint SHOULD make use of the ability to send an incomplete unsettled map (see below) to avoid sending an error.

The unsettled map MUST NOT contain null valued keys.

When reattaching (as opposed to resuming), the unsettled map MUST be null.

incomplete-unsettledoptional boolean

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).

Note that if this flag is set to true then the endpoints MUST detach and reattach at least once in order to send new deliveries. This flag can be useful when there are too many entries in the unsettled map to fit within a single frame. An endpoint can attach, resume, settle, and detach until enough unsettled state has been cleared for an attach where this flag is set to false.

initial-delivery-countthe sender's initial value for delivery-countoptional sequence-no

This MUST NOT be null if role is sender, and it is ignored if the role is receiver. See subsection 2.6.7.

max-message-sizethe maximum message size supported by the link endpointoptional ulong

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 link-error. If this field is zero or unset, there is no maximum size imposed by the link endpoint.

offered-capabilitiesthe extension capabilities the sender supportsoptional symbol[]

A registry of commonly defined link capabilities and their meanings is maintained [AMQPLINKCAP].

desired-capabilitiesthe extension capabilities the sender can use if the receiver supports themoptional symbol[]

The sender MUST NOT attempt to use any capability other than those it has declared in desired-capabilities field.

propertieslink propertiesoptional fields

The properties map contains a set of fields intended to indicate information about the link and its container.

A registry of commonly defined link properties and their meanings is maintained [AMQPLINKPROP].

2.7.4 Flow

Update link state.

<type name="flow" class="composite" source="list" provides="frame"> <descriptor name="amqp:flow:list" code="0x00000000:0x00000013"/> <field name="next-incoming-id" type="transfer-number"/> <field name="incoming-window" type="uint" mandatory="true"/> <field name="next-outgoing-id" type="transfer-number" mandatory="true"/> <field name="outgoing-window" type="uint" mandatory="true"/> <field name="handle" type="handle"/> <field name="delivery-count" type="sequence-no"/> <field name="link-credit" type="uint"/> <field name="available" type="uint"/> <field name="drain" type="boolean" default="false"/> <field name="echo" type="boolean" default="false"/> <field name="properties" type="fields"/> </type>

Updates the flow state for the specified link.

next-incoming-idoptional transfer-number

Identifies the expected transfer-id of the next incoming transfer frame. This value MUST be set if the peer has received the begin frame for the session, and MUST NOT be set if it has not. See subsection 2.5.6 for more details.

incoming-windowmandatory uint

Defines the maximum number of incoming transfer frames that the endpoint can currently receive. See subsection 2.5.6 for more details.

next-outgoing-idmandatory transfer-number

The transfer-id that will be assigned to the next outgoing transfer frame. See subsection 2.5.6 for more details.

outgoing-windowmandatory uint

Defines the maximum number of outgoing transfer frames that the endpoint could potentially currently send, if it was not constrained by restrictions imposed by its peer's incoming-window. See subsection 2.5.6 for more details.

handleoptional handle

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.

If set to a handle that is not currently associated with an attached link, the recipient MUST respond by ending the session with an unattached-handle session error.

delivery-countthe endpoint's value for the delivery-count sequence numberoptional sequence-no

See subsection 2.6.7 for the definition of delivery-count.

When the handle field is not set, this field MUST NOT be set.

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.

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 attach frame from the sender this field MUST NOT be set.

link-creditthe current maximum number of messages that can be receivedoptional uint

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 subsection 2.6.7 for more details.

When the handle field is not set, this field MUST NOT be set.

availablethe number of available messagesoptional uint

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 subsection 2.6.7 for more details.

When the handle field is not set, this field MUST NOT be set.

drainindicates drain modeoptional boolean

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 subsection 2.6.7 for more details.

When the handle field is not set, this field MUST NOT be set.

echorequest state from partneroptional boolean

If set to true then the receiver SHOULD send its state at the earliest convenient opportunity.

If set to true, and the handle field is not set, then the sender only requires session endpoint state to be echoed, however, the receiver MAY fulfil this requirement by sending a flow performative carrying link-specific state (since any such flow also carries session state).

If a sender makes multiple requests for the same state before the receiver can reply, the receiver MAY send only one flow in return.

Note that if a peer responds to echo requests with flows which themselves have the echo field set to true, an infinite loop could result if its partner adopts the same policy (therefore such a policy SHOULD be avoided).

propertieslink state propertiesoptional fields

A registry of commonly defined link state properties and their meanings is maintained [AMQPLINKSTATEPROP].

When the handle field is not set, this field MUST NOT be set.

2.7.5 Transfer

Transfer a message.

<type name="transfer" class="composite" source="list" provides="frame"> <descriptor name="amqp:transfer:list" code="0x00000000:0x00000014"/> <field name="handle" type="handle" mandatory="true"/> <field name="delivery-id" type="delivery-number"/> <field name="delivery-tag" type="delivery-tag"/> <field name="message-format" type="message-format"/> <field name="settled" type="boolean"/> <field name="more" type="boolean" default="false"/> <field name="rcv-settle-mode" type="receiver-settle-mode"/> <field name="state" type="*" requires="delivery-state"/> <field name="resume" type="boolean" default="false"/> <field name="aborted" type="boolean" default="false"/> <field name="batchable" type="boolean" default="false"/> </type>

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.

handlemandatory handle

Specifies the link on which the message is transferred.

delivery-idalias for delivery-tagoptional delivery-number

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.

delivery-tagoptional delivery-tag

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 can only be omitted for continuation transfers. It is an error if the delivery-tag on a continuation transfer differs from the delivery-tag on the first transfer of a delivery.

message-formatindicates the message formatoptional message-format

This field MUST be specified for the first transfer of a multi-transfer message and can only be omitted for continuation transfers. It is an error if the message-format on a continuation transfer differs from the message-format on the first transfer of a delivery.

settledoptional boolean

If not set on the first (or only) transfer for a (multi-transfer) delivery, then the settled flag MUST be interpreted as being false. For subsequent transfers in a multi-transfer delivery 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.

If the negotiated value for snd-settle-mode at attachment is 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).

If the negotiated value for snd-settle-mode at attachment is unsettled, then this field MUST be false (or unset) on every transfer frame for a delivery (unless the delivery is aborted).

moreindicates that the message has more contentoptional boolean

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.

rcv-settle-modeoptional receiver-settle-mode

If first, this indicates that the receiver MUST settle the delivery once it has arrived without waiting for the sender to settle first.

If second, this indicates that the receiver MUST NOT settle until sending its disposition to the sender and receiving a settled disposition from the sender.

If not set, this value is defaulted to the value negotiated on link attach.

If the negotiated link value is first, then it is illegal to set this field to second.

If the message is being sent settled by the sender, the value of this field is ignored.

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.

statethe state of the delivery at the senderoptional *

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 resuming a link. Setting the state on the transfer can be thought of as being equivalent to sending a disposition immediately before the transfer performative, i.e., it is the state of the delivery (not the transfer) that existed at the point the frame was sent.

Note that if the transfer performative (or an earlier disposition performative referring to the delivery) indicates that the delivery has attained a terminal state, then no future transfer or disposition sent by the sender can alter that terminal state.

resumeindicates a resumed deliveryoptional boolean

If true, the resume flag indicates that the transfer is being used to reassociate an unsettled delivery from a dissociated link endpoint. See subsection 2.6.13 for more details.

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.

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.

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.

abortedindicates that the message is abortedoptional boolean

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.

batchablebatchable hintoptional boolean

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.

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 transfer performatives for the delivery is equivalent to setting batchable to true for all the transfer performatives for the delivery.

The batchable value does not form part of the transfer state, and is not retained if a link is suspended and subsequently resumed.

2.7.6 Disposition

Inform remote peer of delivery state changes.

<type name="disposition" class="composite" source="list" provides="frame"> <descriptor name="amqp:disposition:list" code="0x00000000:0x00000015"/> <field name="role" type="role" mandatory="true"/> <field name="first" type="delivery-number" mandatory="true"/> <field name="last" type="delivery-number"/> <field name="settled" type="boolean" default="false"/> <field name="state" type="*" requires="delivery-state"/> <field name="batchable" type="boolean" default="false"/> </type>

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 role.

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 transfer performative for the delivery.

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.

roledirectionality of dispositionmandatory role

The role identifies whether the disposition frame contains information about sending link endpoints or receiving link endpoints.

firstlower bound of deliveriesmandatory delivery-number

Identifies the lower bound of delivery-ids for the deliveries in this set.

lastupper bound of deliveriesoptional delivery-number

Identifies the upper bound of delivery-ids for the deliveries in this set. If not set, this is taken to be the same as first.

settledindicates deliveries are settledoptional boolean

If true, indicates that the referenced deliveries are considered settled by the issuing endpoint.

stateindicates state of deliveriesoptional *

Communicates the state of all the deliveries referenced by this disposition.

batchablebatchable hintoptional boolean

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.

2.7.7 Detach

Detach the link endpoint from the session.

<type name="detach" class="composite" source="list" provides="frame"> <descriptor name="amqp:detach:list" code="0x00000000:0x00000016"/> <field name="handle" type="handle" mandatory="true"/> <field name="closed" type="boolean" default="false"/> <field name="error" type="error"/> </type>

Detach the link endpoint from the session. This unmaps the handle and makes it available for use by other links.

handlethe local handle of the link to be detachedmandatory handle
closedif true then the sender has closed the linkoptional boolean
errorerror causing the detachoptional error

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.

2.7.8 End

End the session.

<type name="end" class="composite" source="list" provides="frame"> <descriptor name="amqp:end:list" code="0x00000000:0x00000017"/> <field name="error" type="error"/> </type>

Indicates that the session has ended.

errorerror causing the endoptional error

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.

2.7.9 Close

Signal a connection close.

<type name="close" class="composite" source="list" provides="frame"> <descriptor name="amqp:close:list" code="0x00000000:0x00000018"/> <field name="error" type="error"/> </type>

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.

errorerror causing the closeoptional error

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.

2.8 Definitions

2.8.1 Role

Link endpoint role.

<type name="role" class="restricted" source="boolean"> <choice name="sender" value="false"/> <choice name="receiver" value="true"/> </type>
senderfalse
receivertrue

2.8.2 Sender Settle Mode

Settlement policy for a sender.

<type name="sender-settle-mode" class="restricted" source="ubyte"> <choice name="unsettled" value="0"/> <choice name="settled" value="1"/> <choice name="mixed" value="2"/> </type>
unsettled0

The sender will send all deliveries initially unsettled to the receiver.

settled1

The sender will send all deliveries settled to the receiver.

mixed2

The sender MAY send a mixture of settled and unsettled deliveries to the receiver.

2.8.3 Receiver Settle Mode

Settlement policy for a receiver.

<type name="receiver-settle-mode" class="restricted" source="ubyte"> <choice name="first" value="0"/> <choice name="second" value="1"/> </type>
first0

The receiver will spontaneously settle all incoming transfers.

second1

The receiver will only settle after sending the disposition to the sender and receiving a disposition indicating settlement of the delivery from the sender.

2.8.4 Handle

The handle of a link.

<type name="handle" class="restricted" source="uint"/>

An alias established by the 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.

2.8.5 Seconds

A duration measured in seconds.

<type name="seconds" class="restricted" source="uint"/>

2.8.6 Milliseconds

A duration measured in milliseconds.

<type name="milliseconds" class="restricted" source="uint"/>

2.8.7 Delivery Tag

<type name="delivery-tag" class="restricted" source="binary"/>

A delivery-tag can be up to 32 octets of binary data.

2.8.8 Delivery Number

<type name="delivery-number" class="restricted" source="sequence-no"/>

2.8.9 Transfer Number

<type name="transfer-number" class="restricted" source="sequence-no"/>

2.8.10 Sequence No

32-bit RFC-1982 serial number.

<type name="sequence-no" class="restricted" source="uint"/>

A sequence-no encodes a serial number as defined in RFC-1982 [RFC1982]. The arithmetic and operators for these numbers are defined by RFC-1982.

2.8.11 Message Format

32-bit message format code.

<type name="message-format" class="restricted" source="uint"/>

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.

Figure 2.59: Layout of Message Format Code
3 octets 1 octet +----------------+---------+ | message format | version | +----------------+---------+ | | msb lsb

2.8.12 Ietf Language Tag

An IETF language tag as defined by BCP 47.

<type name="ietf-language-tag" class="restricted" source="symbol"/>

IETF language tags are abbreviated language codes as defined in the IETF Best Current Practice BCP-47 [BCP47] (incorporating IETF RFC-5646 [RFC5646]). A list of registered subtags is maintained in the IANA Language Subtag Registry [IANASUBTAG].

All AMQP implementations SHOULD understand at the least the IETF language tag en-US (note that this uses a hyphen separator, not an underscore).

2.8.13 Fields

A mapping from field name to value.

<type name="fields" class="restricted" source="map"/>

The fields type is a map where the keys are restricted to be of type symbol (this excludes the possibility of a null key). There is no further restriction implied by the fields type on the allowed values for the entries or the set of allowed keys.

2.8.14 Error

Details of an error.

<type name="error" class="composite" source="list"> <descriptor name="amqp:error:list" code="0x00000000:0x0000001d"/> <field name="condition" type="symbol" requires="error-condition" mandatory="true"/> <field name="description" type="string"/> <field name="info" type="fields"/> </type>
conditionerror conditionmandatory symbol

A symbolic value indicating the error condition.

descriptiondescriptive text about the error conditionoptional string

This text supplies any supplementary details not indicated by the condition field. This text can be logged as an aid to resolving issues.

infomap carrying information about the error conditionoptional fields

2.8.15 Amqp Error

Shared error conditions.

<type name="amqp-error" class="restricted" source="symbol" provides="error-condition"> <choice name="internal-error" value="amqp:internal-error"/> <choice name="not-found" value="amqp:not-found"/> <choice name="unauthorized-access" value="amqp:unauthorized-access"/> <choice name="decode-error" value="amqp:decode-error"/> <choice name="resource-limit-exceeded" value="amqp:resource-limit-exceeded"/> <choice name="not-allowed" value="amqp:not-allowed"/> <choice name="invalid-field" value="amqp:invalid-field"/> <choice name="not-implemented" value="amqp:not-implemented"/> <choice name="resource-locked" value="amqp:resource-locked"/> <choice name="precondition-failed" value="amqp:precondition-failed"/> <choice name="resource-deleted" value="amqp:resource-deleted"/> <choice name="illegal-state" value="amqp:illegal-state"/> <choice name="frame-size-too-small" value="amqp:frame-size-too-small"/> </type>
internal-erroramqp:internal-error

An internal error occurred. Operator intervention might be necessary to resume normal operation.

not-foundamqp:not-found

A peer attempted to work with a remote entity that does not exist.

unauthorized-accessamqp:unauthorized-access

A peer attempted to work with a remote entity to which it has no access due to security settings.

decode-erroramqp:decode-error

Data could not be decoded.

resource-limit-exceededamqp:resource-limit-exceeded

A peer exceeded its resource allocation.

not-allowedamqp:not-allowed

The peer tried to use a frame in a manner that is inconsistent with the semantics defined in the specification.

invalid-fieldamqp:invalid-field

An invalid field was passed in a frame body, and the operation could not proceed.

not-implementedamqp:not-implemented

The peer tried to use functionality that is not implemented in its partner.

resource-lockedamqp:resource-locked

The client attempted to work with a server entity to which it has no access because another client is working with it.

precondition-failedamqp:precondition-failed

The client made a request that was not allowed because some precondition failed.

resource-deletedamqp:resource-deleted

A server entity the client is working with has been deleted.

illegal-stateamqp:illegal-state

The peer sent a frame that is not permitted in the current state.

frame-size-too-smallamqp:frame-size-too-small

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 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.

2.8.16 Connection Error

Symbols used to indicate connection error conditions.

<type name="connection-error" class="restricted" source="symbol" provides="error-condition"> <choice name="connection-forced" value="amqp:connection:forced"/> <choice name="framing-error" value="amqp:connection:framing-error"/> <choice name="redirect" value="amqp:connection:redirect"/> </type>
connection-forcedamqp:connection:forced

An operator intervened to close the connection for some reason. The client could retry at some later date.

framing-erroramqp:connection:framing-error

A valid frame header cannot be formed from the incoming byte stream.

redirectamqp:connection:redirect

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.

hostname

the hostname of the container. This is the value that SHOULD be supplied in the hostname field of the open frame, and during the SASL and TLS negotiation (if used).

network-host

the DNS hostname or IP address of the machine hosting the container.

port

the port number on the machine hosting the container.

2.8.17 Session Error

Symbols used to indicate session error conditions.

<type name="session-error" class="restricted" source="symbol" provides="error-condition"> <choice name="window-violation" value="amqp:session:window-violation"/> <choice name="errant-link" value="amqp:session:errant-link"/> <choice name="handle-in-use" value="amqp:session:handle-in-use"/> <choice name="unattached-handle" value="amqp:session:unattached-handle"/> </type>
window-violationamqp:session:window-violation

The peer violated incoming window for the session.

errant-linkamqp:session:errant-link

Input was received for a link that was detached with an error.

handle-in-useamqp:session:handle-in-use

An attach was received using a handle that is already in use for an attached link.

unattached-handleamqp:session:unattached-handle

A frame (other than attach) was received referencing a handle which is not currently in use of an attached link.

2.8.18 Link Error

Symbols used to indicate link error conditions.

<type name="link-error" class="restricted" source="symbol" provides="error-condition"> <choice name="detach-forced" value="amqp:link:detach-forced"/> <choice name="transfer-limit-exceeded" value="amqp:link:transfer-limit-exceeded"/> <choice name="message-size-exceeded" value="amqp:link:message-size-exceeded"/> <choice name="redirect" value="amqp:link:redirect"/> <choice name="stolen" value="amqp:link:stolen"/> </type>
detach-forcedamqp:link:detach-forced

An operator intervened to detach for some reason.

transfer-limit-exceededamqp:link:transfer-limit-exceeded

The peer sent more message transfers than currently allowed on the link.

message-size-exceededamqp:link:message-size-exceeded

The peer sent a larger message than is supported on the link.

redirectamqp:link:redirect

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.

hostname

the hostname of the container hosting the terminus. This is the value that SHOULD be supplied in the hostname field of the open frame, and during SASL and TLS negotiation (if used).

network-host

the DNS hostname or IP address of the machine hosting the container.

port

the port number on the machine hosting the container.

address

the address of the terminus at the container.

stolenamqp:link:stolen

The link has been attached elsewhere, causing the existing attachment to be forcibly closed.

2.8.19 Constant Definitions

PORT5672the IANA assigned port number for AMQP.

The standard AMQP port number that has been assigned by IANA for TCP, UDP, and SCTP.

There are currently no UDP or SCTP mappings defined for AMQP. The port number is reserved for future transport mappings to these protocols.

SECURE-PORT5671the IANA assigned port number for secure AMQP (amqps).

The standard AMQP port number that has been assigned by IANA for secure TCP using TLS.

Implementations listening on this port SHOULD NOT expect a protocol handshake before TLS is negotiated.

MAJOR1major protocol version.
MINOR0minor protocol version.
REVISION0protocol revision.
MIN-MAX-FRAME-SIZE512the lower bound for the agreed maximum frame size (in bytes).

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.


<< Part 1: Types Part 3: Messaging >>