From de1fc43cc58ce6a02c6eeef7791328c44189aa7c Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Mon, 4 Mar 2019 16:27:39 -0800 Subject: [PATCH] added librabbitmq library for central controller --- controller/PostgreSQL.cpp | 1 + ext/librabbitmq/centos_x64/include/amqp.h | 2538 +++++++++++++++++ .../centos_x64/include/amqp_framing.h | 1144 ++++++++ .../centos_x64/include/amqp_tcp_socket.h | 68 + ext/librabbitmq/centos_x64/lib/librabbitmq.a | Bin 0 -> 134844 bytes make-linux.mk | 2 +- 6 files changed, 3752 insertions(+), 1 deletion(-) create mode 100644 ext/librabbitmq/centos_x64/include/amqp.h create mode 100644 ext/librabbitmq/centos_x64/include/amqp_framing.h create mode 100644 ext/librabbitmq/centos_x64/include/amqp_tcp_socket.h create mode 100644 ext/librabbitmq/centos_x64/lib/librabbitmq.a diff --git a/controller/PostgreSQL.cpp b/controller/PostgreSQL.cpp index 6165d8c49..9eb64800d 100644 --- a/controller/PostgreSQL.cpp +++ b/controller/PostgreSQL.cpp @@ -32,6 +32,7 @@ #include #include +#include using json = nlohmann::json; namespace { diff --git a/ext/librabbitmq/centos_x64/include/amqp.h b/ext/librabbitmq/centos_x64/include/amqp.h new file mode 100644 index 000000000..2983b1665 --- /dev/null +++ b/ext/librabbitmq/centos_x64/include/amqp.h @@ -0,0 +1,2538 @@ +/** \file */ +/* + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2014 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +#ifndef AMQP_H +#define AMQP_H + +/** \cond HIDE_FROM_DOXYGEN */ + +#ifdef __cplusplus +#define AMQP_BEGIN_DECLS extern "C" { +#define AMQP_END_DECLS } +#else +#define AMQP_BEGIN_DECLS +#define AMQP_END_DECLS +#endif + +/* + * \internal + * Important API decorators: + * AMQP_PUBLIC_FUNCTION - a public API function + * AMQP_PUBLIC_VARIABLE - a public API external variable + * AMQP_CALL - calling convension (used on Win32) + */ + +#if defined(_WIN32) && defined(_MSC_VER) +#if defined(AMQP_BUILD) && !defined(AMQP_STATIC) +#define AMQP_PUBLIC_FUNCTION __declspec(dllexport) +#define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern +#else +#define AMQP_PUBLIC_FUNCTION +#if !defined(AMQP_STATIC) +#define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern +#else +#define AMQP_PUBLIC_VARIABLE extern +#endif +#endif +#define AMQP_CALL __cdecl + +#elif defined(_WIN32) && defined(__BORLANDC__) +#if defined(AMQP_BUILD) && !defined(AMQP_STATIC) +#define AMQP_PUBLIC_FUNCTION __declspec(dllexport) +#define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern +#else +#define AMQP_PUBLIC_FUNCTION +#if !defined(AMQP_STATIC) +#define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern +#else +#define AMQP_PUBLIC_VARIABLE extern +#endif +#endif +#define AMQP_CALL __cdecl + +#elif defined(_WIN32) && defined(__MINGW32__) +#if defined(AMQP_BUILD) && !defined(AMQP_STATIC) +#define AMQP_PUBLIC_FUNCTION __declspec(dllexport) +#define AMQP_PUBLIC_VARIABLE __declspec(dllexport) extern +#else +#define AMQP_PUBLIC_FUNCTION +#if !defined(AMQP_STATIC) +#define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern +#else +#define AMQP_PUBLIC_VARIABLE extern +#endif +#endif +#define AMQP_CALL __cdecl + +#elif defined(_WIN32) && defined(__CYGWIN__) +#if defined(AMQP_BUILD) && !defined(AMQP_STATIC) +#define AMQP_PUBLIC_FUNCTION __declspec(dllexport) +#define AMQP_PUBLIC_VARIABLE __declspec(dllexport) +#else +#define AMQP_PUBLIC_FUNCTION +#if !defined(AMQP_STATIC) +#define AMQP_PUBLIC_VARIABLE __declspec(dllimport) extern +#else +#define AMQP_PUBLIC_VARIABLE extern +#endif +#endif +#define AMQP_CALL __cdecl + +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define AMQP_PUBLIC_FUNCTION __attribute__((visibility("default"))) +#define AMQP_PUBLIC_VARIABLE __attribute__((visibility("default"))) extern +#define AMQP_CALL +#else +#define AMQP_PUBLIC_FUNCTION +#define AMQP_PUBLIC_VARIABLE extern +#define AMQP_CALL +#endif + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define AMQP_DEPRECATED(function) function __attribute__((__deprecated__)) +#elif defined(_MSC_VER) +#define AMQP_DEPRECATED(function) __declspec(deprecated) function +#else +#define AMQP_DEPRECATED(function) +#endif + +/* Define ssize_t on Win32/64 platforms + See: http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-April/030649.html for + details + */ +#if !defined(_W64) +#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +#define _W64 __w64 +#else +#define _W64 +#endif +#endif + +#ifdef _MSC_VER +#ifdef _WIN64 +typedef __int64 ssize_t; +#else +typedef _W64 int ssize_t; +#endif +#endif + +#if defined(_WIN32) && defined(__MINGW32__) +#include +#endif + +/** \endcond */ + +#include +#include + +struct timeval; + +AMQP_BEGIN_DECLS + +/** + * \def AMQP_VERSION_MAJOR + * + * Major library version number compile-time constant + * + * The major version is incremented when backwards incompatible API changes + * are made. + * + * \sa AMQP_VERSION, AMQP_VERSION_STRING + * + * \since v0.4.0 + */ + +/** + * \def AMQP_VERSION_MINOR + * + * Minor library version number compile-time constant + * + * The minor version is incremented when new APIs are added. Existing APIs + * are left alone. + * + * \sa AMQP_VERSION, AMQP_VERSION_STRING + * + * \since v0.4.0 + */ + +/** + * \def AMQP_VERSION_PATCH + * + * Patch library version number compile-time constant + * + * The patch version is incremented when library code changes, but the API + * is not changed. + * + * \sa AMQP_VERSION, AMQP_VERSION_STRING + * + * \since v0.4.0 + */ + +/** + * \def AMQP_VERSION_IS_RELEASE + * + * Version constant set to 1 for tagged release, 0 otherwise + * + * NOTE: versions that are not tagged releases are not guaranteed to be API/ABI + * compatible with older releases, and may change commit-to-commit. + * + * \sa AMQP_VERSION, AMQP_VERSION_STRING + * + * \since v0.4.0 + */ +/* + * Developer note: when changing these, be sure to update SOVERSION constants + * in CMakeLists.txt and configure.ac + */ + +#define AMQP_VERSION_MAJOR 0 +#define AMQP_VERSION_MINOR 10 +#define AMQP_VERSION_PATCH 0 +#define AMQP_VERSION_IS_RELEASE 0 + +/** + * \def AMQP_VERSION_CODE + * + * Helper macro to geneate a packed version code suitable for + * comparison with AMQP_VERSION. + * + * \sa amqp_version_number() AMQP_VERSION_MAJOR, AMQP_VERSION_MINOR, + * AMQP_VERSION_PATCH, AMQP_VERSION_IS_RELEASE, AMQP_VERSION + * + * \since v0.6.1 + */ +#define AMQP_VERSION_CODE(major, minor, patch, release) \ + ((major << 24) | (minor << 16) | (patch << 8) | (release)) + +/** + * \def AMQP_VERSION + * + * Packed version number + * + * AMQP_VERSION is a 4-byte unsigned integer with the most significant byte + * set to AMQP_VERSION_MAJOR, the second most significant byte set to + * AMQP_VERSION_MINOR, third most significant byte set to AMQP_VERSION_PATCH, + * and the lowest byte set to AMQP_VERSION_IS_RELEASE. + * + * For example version 2.3.4 which is released version would be encoded as + * 0x02030401 + * + * \sa amqp_version_number() AMQP_VERSION_MAJOR, AMQP_VERSION_MINOR, + * AMQP_VERSION_PATCH, AMQP_VERSION_IS_RELEASE, AMQP_VERSION_CODE + * + * \since v0.4.0 + */ +#define AMQP_VERSION \ + AMQP_VERSION_CODE(AMQP_VERSION_MAJOR, AMQP_VERSION_MINOR, \ + AMQP_VERSION_PATCH, AMQP_VERSION_IS_RELEASE) + +/** \cond HIDE_FROM_DOXYGEN */ +#define AMQ_STRINGIFY(s) AMQ_STRINGIFY_HELPER(s) +#define AMQ_STRINGIFY_HELPER(s) #s + +#define AMQ_VERSION_STRING \ + AMQ_STRINGIFY(AMQP_VERSION_MAJOR) \ + "." AMQ_STRINGIFY(AMQP_VERSION_MINOR) "." AMQ_STRINGIFY(AMQP_VERSION_PATCH) +/** \endcond */ + +/** + * \def AMQP_VERSION_STRING + * + * Version string compile-time constant + * + * Non-released versions of the library will have "-pre" appended to the + * version string + * + * \sa amqp_version() + * + * \since v0.4.0 + */ +#if AMQP_VERSION_IS_RELEASE +#define AMQP_VERSION_STRING AMQ_VERSION_STRING +#else +#define AMQP_VERSION_STRING AMQ_VERSION_STRING "-pre" +#endif + +/** + * Returns the rabbitmq-c version as a packed integer. + * + * See \ref AMQP_VERSION + * + * \return packed 32-bit integer representing version of library at runtime + * + * \sa AMQP_VERSION, amqp_version() + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +uint32_t AMQP_CALL amqp_version_number(void); + +/** + * Returns the rabbitmq-c version as a string. + * + * See \ref AMQP_VERSION_STRING + * + * \return a statically allocated string describing the version of rabbitmq-c. + * + * \sa amqp_version_number(), AMQP_VERSION_STRING, AMQP_VERSION + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +char const *AMQP_CALL amqp_version(void); + +/** + * \def AMQP_DEFAULT_FRAME_SIZE + * + * Default frame size (128Kb) + * + * \sa amqp_login(), amqp_login_with_properties() + * + * \since v0.4.0 + */ +#define AMQP_DEFAULT_FRAME_SIZE 131072 + +/** + * \def AMQP_DEFAULT_MAX_CHANNELS + * + * Default maximum number of channels (2047, RabbitMQ default limit of 2048, + * minus 1 for channel 0). RabbitMQ set a default limit of 2048 channels per + * connection in v3.7.5 to prevent broken clients from leaking too many + * channels. + * + * \sa amqp_login(), amqp_login_with_properties() + * + * \since v0.4.0 + */ +#define AMQP_DEFAULT_MAX_CHANNELS 2047 + +/** + * \def AMQP_DEFAULT_HEARTBEAT + * + * Default heartbeat interval (0, heartbeat disabled) + * + * \sa amqp_login(), amqp_login_with_properties() + * + * \since v0.4.0 + */ +#define AMQP_DEFAULT_HEARTBEAT 0 + +/** + * \def AMQP_DEFAULT_VHOST + * + * Default RabbitMQ vhost: "/" + * + * \sa amqp_login(), amqp_login_with_properties() + * + * \since v0.9.0 + */ +#define AMQP_DEFAULT_VHOST "/" + +/** + * boolean type 0 = false, true otherwise + * + * \since v0.1 + */ +typedef int amqp_boolean_t; + +/** + * Method number + * + * \since v0.1 + */ +typedef uint32_t amqp_method_number_t; + +/** + * Bitmask for flags + * + * \since v0.1 + */ +typedef uint32_t amqp_flags_t; + +/** + * Channel type + * + * \since v0.1 + */ +typedef uint16_t amqp_channel_t; + +/** + * Buffer descriptor + * + * \since v0.1 + */ +typedef struct amqp_bytes_t_ { + size_t len; /**< length of the buffer in bytes */ + void *bytes; /**< pointer to the beginning of the buffer */ +} amqp_bytes_t; + +/** + * Decimal data type + * + * \since v0.1 + */ +typedef struct amqp_decimal_t_ { + uint8_t decimals; /**< the location of the decimal point */ + uint32_t value; /**< the value before the decimal point is applied */ +} amqp_decimal_t; + +/** + * AMQP field table + * + * An AMQP field table is a set of key-value pairs. + * A key is a UTF-8 encoded string up to 128 bytes long, and are not null + * terminated. + * A value can be one of several different datatypes. \sa + * amqp_field_value_kind_t + * + * \sa amqp_table_entry_t + * + * \since v0.1 + */ +typedef struct amqp_table_t_ { + int num_entries; /**< length of entries array */ + struct amqp_table_entry_t_ *entries; /**< an array of table entries */ +} amqp_table_t; + +/** + * An AMQP Field Array + * + * A repeated set of field values, all must be of the same type + * + * \since v0.1 + */ +typedef struct amqp_array_t_ { + int num_entries; /**< Number of entries in the table */ + struct amqp_field_value_t_ *entries; /**< linked list of field values */ +} amqp_array_t; + +/* + 0-9 0-9-1 Qpid/Rabbit Type Remarks +--------------------------------------------------------------------------- + t t Boolean + b b Signed 8-bit + B Unsigned 8-bit + U s Signed 16-bit (A1) + u Unsigned 16-bit + I I I Signed 32-bit + i Unsigned 32-bit + L l Signed 64-bit (B) + l Unsigned 64-bit + f f 32-bit float + d d 64-bit float + D D D Decimal + s Short string (A2) + S S S Long string + A Nested Array + T T T Timestamp (u64) + F F F Nested Table + V V V Void + x Byte array + +Remarks: + + A1, A2: Notice how the types **CONFLICT** here. In Qpid and Rabbit, + 's' means a signed 16-bit integer; in 0-9-1, it means a + short string. + + B: Notice how the signednesses **CONFLICT** here. In Qpid and Rabbit, + 'l' means a signed 64-bit integer; in 0-9-1, it means an unsigned + 64-bit integer. + +I'm going with the Qpid/Rabbit types, where there's a conflict, and +the 0-9-1 types otherwise. 0-8 is a subset of 0-9, which is a subset +of the other two, so this will work for both 0-8 and 0-9-1 branches of +the code. +*/ + +/** + * A field table value + * + * \since v0.1 + */ +typedef struct amqp_field_value_t_ { + uint8_t kind; /**< the type of the entry /sa amqp_field_value_kind_t */ + union { + amqp_boolean_t boolean; /**< boolean type AMQP_FIELD_KIND_BOOLEAN */ + int8_t i8; /**< int8_t type AMQP_FIELD_KIND_I8 */ + uint8_t u8; /**< uint8_t type AMQP_FIELD_KIND_U8 */ + int16_t i16; /**< int16_t type AMQP_FIELD_KIND_I16 */ + uint16_t u16; /**< uint16_t type AMQP_FIELD_KIND_U16 */ + int32_t i32; /**< int32_t type AMQP_FIELD_KIND_I32 */ + uint32_t u32; /**< uint32_t type AMQP_FIELD_KIND_U32 */ + int64_t i64; /**< int64_t type AMQP_FIELD_KIND_I64 */ + uint64_t u64; /**< uint64_t type AMQP_FIELD_KIND_U64, + AMQP_FIELD_KIND_TIMESTAMP */ + float f32; /**< float type AMQP_FIELD_KIND_F32 */ + double f64; /**< double type AMQP_FIELD_KIND_F64 */ + amqp_decimal_t decimal; /**< amqp_decimal_t AMQP_FIELD_KIND_DECIMAL */ + amqp_bytes_t bytes; /**< amqp_bytes_t type AMQP_FIELD_KIND_UTF8, + AMQP_FIELD_KIND_BYTES */ + amqp_table_t table; /**< amqp_table_t type AMQP_FIELD_KIND_TABLE */ + amqp_array_t array; /**< amqp_array_t type AMQP_FIELD_KIND_ARRAY */ + } value; /**< a union of the value */ +} amqp_field_value_t; + +/** + * An entry in a field-table + * + * \sa amqp_table_encode(), amqp_table_decode(), amqp_table_clone() + * + * \since v0.1 + */ +typedef struct amqp_table_entry_t_ { + amqp_bytes_t key; /**< the table entry key. Its a null-terminated UTF-8 + * string, with a maximum size of 128 bytes */ + amqp_field_value_t value; /**< the table entry values */ +} amqp_table_entry_t; + +/** + * Field value types + * + * \since v0.1 + */ +typedef enum { + AMQP_FIELD_KIND_BOOLEAN = + 't', /**< boolean type. 0 = false, 1 = true @see amqp_boolean_t */ + AMQP_FIELD_KIND_I8 = 'b', /**< 8-bit signed integer, datatype: int8_t */ + AMQP_FIELD_KIND_U8 = 'B', /**< 8-bit unsigned integer, datatype: uint8_t */ + AMQP_FIELD_KIND_I16 = 's', /**< 16-bit signed integer, datatype: int16_t */ + AMQP_FIELD_KIND_U16 = 'u', /**< 16-bit unsigned integer, datatype: uint16_t */ + AMQP_FIELD_KIND_I32 = 'I', /**< 32-bit signed integer, datatype: int32_t */ + AMQP_FIELD_KIND_U32 = 'i', /**< 32-bit unsigned integer, datatype: uint32_t */ + AMQP_FIELD_KIND_I64 = 'l', /**< 64-bit signed integer, datatype: int64_t */ + AMQP_FIELD_KIND_U64 = 'L', /**< 64-bit unsigned integer, datatype: uint64_t */ + AMQP_FIELD_KIND_F32 = + 'f', /**< single-precision floating point value, datatype: float */ + AMQP_FIELD_KIND_F64 = + 'd', /**< double-precision floating point value, datatype: double */ + AMQP_FIELD_KIND_DECIMAL = + 'D', /**< amqp-decimal value, datatype: amqp_decimal_t */ + AMQP_FIELD_KIND_UTF8 = 'S', /**< UTF-8 null-terminated character string, + datatype: amqp_bytes_t */ + AMQP_FIELD_KIND_ARRAY = 'A', /**< field array (repeated values of another + datatype. datatype: amqp_array_t */ + AMQP_FIELD_KIND_TIMESTAMP = 'T', /**< 64-bit timestamp. datatype uint64_t */ + AMQP_FIELD_KIND_TABLE = 'F', /**< field table. encapsulates a table inside a + table entry. datatype: amqp_table_t */ + AMQP_FIELD_KIND_VOID = 'V', /**< empty entry */ + AMQP_FIELD_KIND_BYTES = + 'x' /**< unformatted byte string, datatype: amqp_bytes_t */ +} amqp_field_value_kind_t; + +/** + * A list of allocation blocks + * + * \since v0.1 + */ +typedef struct amqp_pool_blocklist_t_ { + int num_blocks; /**< Number of blocks in the block list */ + void **blocklist; /**< Array of memory blocks */ +} amqp_pool_blocklist_t; + +/** + * A memory pool + * + * \since v0.1 + */ +typedef struct amqp_pool_t_ { + size_t pagesize; /**< the size of the page in bytes. Allocations less than or + * equal to this size are allocated in the pages block list. + * Allocations greater than this are allocated in their own + * own block in the large_blocks block list */ + + amqp_pool_blocklist_t pages; /**< blocks that are the size of pagesize */ + amqp_pool_blocklist_t + large_blocks; /**< allocations larger than the pagesize */ + + int next_page; /**< an index to the next unused page block */ + char *alloc_block; /**< pointer to the current allocation block */ + size_t alloc_used; /**< number of bytes in the current allocation block that + has been used */ +} amqp_pool_t; + +/** + * An amqp method + * + * \since v0.1 + */ +typedef struct amqp_method_t_ { + amqp_method_number_t id; /**< the method id number */ + void *decoded; /**< pointer to the decoded method, + * cast to the appropriate type to use */ +} amqp_method_t; + +/** + * An AMQP frame + * + * \since v0.1 + */ +typedef struct amqp_frame_t_ { + uint8_t frame_type; /**< frame type. The types: + * - AMQP_FRAME_METHOD - use the method union member + * - AMQP_FRAME_HEADER - use the properties union member + * - AMQP_FRAME_BODY - use the body_fragment union member + */ + amqp_channel_t channel; /**< the channel the frame was received on */ + union { + amqp_method_t + method; /**< a method, use if frame_type == AMQP_FRAME_METHOD */ + struct { + uint16_t class_id; /**< the class for the properties */ + uint64_t body_size; /**< size of the body in bytes */ + void *decoded; /**< the decoded properties */ + amqp_bytes_t raw; /**< amqp-encoded properties structure */ + } properties; /**< message header, a.k.a., properties, + use if frame_type == AMQP_FRAME_HEADER */ + amqp_bytes_t body_fragment; /**< a body fragment, use if frame_type == + AMQP_FRAME_BODY */ + struct { + uint8_t transport_high; /**< @internal first byte of handshake */ + uint8_t transport_low; /**< @internal second byte of handshake */ + uint8_t protocol_version_major; /**< @internal third byte of handshake */ + uint8_t protocol_version_minor; /**< @internal fourth byte of handshake */ + } protocol_header; /**< Used only when doing the initial handshake with the + broker, don't use otherwise */ + } payload; /**< the payload of the frame */ +} amqp_frame_t; + +/** + * Response type + * + * \since v0.1 + */ +typedef enum amqp_response_type_enum_ { + AMQP_RESPONSE_NONE = 0, /**< the library got an EOF from the socket */ + AMQP_RESPONSE_NORMAL, /**< response normal, the RPC completed successfully */ + AMQP_RESPONSE_LIBRARY_EXCEPTION, /**< library error, an error occurred in the + library, examine the library_error */ + AMQP_RESPONSE_SERVER_EXCEPTION /**< server exception, the broker returned an + error, check replay */ +} amqp_response_type_enum; + +/** + * Reply from a RPC method on the broker + * + * \since v0.1 + */ +typedef struct amqp_rpc_reply_t_ { + amqp_response_type_enum reply_type; /**< the reply type: + * - AMQP_RESPONSE_NORMAL - the RPC + * completed successfully + * - AMQP_RESPONSE_SERVER_EXCEPTION - the + * broker returned + * an exception, check the reply field + * - AMQP_RESPONSE_LIBRARY_EXCEPTION - the + * library + * encountered an error, check the + * library_error field + */ + amqp_method_t reply; /**< in case of AMQP_RESPONSE_SERVER_EXCEPTION this + * field will be set to the method returned from the + * broker */ + int library_error; /**< in case of AMQP_RESPONSE_LIBRARY_EXCEPTION this + * field will be set to an error code. An error + * string can be retrieved using amqp_error_string */ +} amqp_rpc_reply_t; + +/** + * SASL method type + * + * \since v0.1 + */ +typedef enum amqp_sasl_method_enum_ { + AMQP_SASL_METHOD_UNDEFINED = -1, /**< Invalid SASL method */ + AMQP_SASL_METHOD_PLAIN = + 0, /**< the PLAIN SASL method for authentication to the broker */ + AMQP_SASL_METHOD_EXTERNAL = + 1 /**< the EXTERNAL SASL method for authentication to the broker */ +} amqp_sasl_method_enum; + +/** + * connection state object + * + * \since v0.1 + */ +typedef struct amqp_connection_state_t_ *amqp_connection_state_t; + +/** + * Socket object + * + * \since v0.4.0 + */ +typedef struct amqp_socket_t_ amqp_socket_t; + +/** + * Status codes + * + * \since v0.4.0 + */ +/* NOTE: When updating this enum, update the strings in librabbitmq/amqp_api.c + */ +typedef enum amqp_status_enum_ { + AMQP_STATUS_OK = 0x0, /**< Operation successful */ + AMQP_STATUS_NO_MEMORY = -0x0001, /**< Memory allocation + failed */ + AMQP_STATUS_BAD_AMQP_DATA = -0x0002, /**< Incorrect or corrupt + data was received from + the broker. This is a + protocol error. */ + AMQP_STATUS_UNKNOWN_CLASS = -0x0003, /**< An unknown AMQP class + was received. This is + a protocol error. */ + AMQP_STATUS_UNKNOWN_METHOD = -0x0004, /**< An unknown AMQP method + was received. This is + a protocol error. */ + AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED = -0x0005, /**< Unable to resolve the + * hostname */ + AMQP_STATUS_INCOMPATIBLE_AMQP_VERSION = -0x0006, /**< The broker advertised + an incompaible AMQP + version */ + AMQP_STATUS_CONNECTION_CLOSED = -0x0007, /**< The connection to the + broker has been closed + */ + AMQP_STATUS_BAD_URL = -0x0008, /**< malformed AMQP URL */ + AMQP_STATUS_SOCKET_ERROR = -0x0009, /**< A socket error + occurred */ + AMQP_STATUS_INVALID_PARAMETER = -0x000A, /**< An invalid parameter + was passed into the + function */ + AMQP_STATUS_TABLE_TOO_BIG = -0x000B, /**< The amqp_table_t object + cannot be serialized + because the output + buffer is too small */ + AMQP_STATUS_WRONG_METHOD = -0x000C, /**< The wrong method was + received */ + AMQP_STATUS_TIMEOUT = -0x000D, /**< Operation timed out */ + AMQP_STATUS_TIMER_FAILURE = -0x000E, /**< The underlying system + timer facility failed */ + AMQP_STATUS_HEARTBEAT_TIMEOUT = -0x000F, /**< Timed out waiting for + heartbeat */ + AMQP_STATUS_UNEXPECTED_STATE = -0x0010, /**< Unexpected protocol + state */ + AMQP_STATUS_SOCKET_CLOSED = -0x0011, /**< Underlying socket is + closed */ + AMQP_STATUS_SOCKET_INUSE = -0x0012, /**< Underlying socket is + already open */ + AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD = -0x0013, /**< Broker does not + support the requested + SASL mechanism */ + AMQP_STATUS_UNSUPPORTED = -0x0014, /**< Parameter is unsupported + in this version */ + _AMQP_STATUS_NEXT_VALUE = -0x0015, /**< Internal value */ + + AMQP_STATUS_TCP_ERROR = -0x0100, /**< A generic TCP error + occurred */ + AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR = -0x0101, /**< An error occurred trying + to initialize the + socket library*/ + _AMQP_STATUS_TCP_NEXT_VALUE = -0x0102, /**< Internal value */ + + AMQP_STATUS_SSL_ERROR = -0x0200, /**< A generic SSL error + occurred. */ + AMQP_STATUS_SSL_HOSTNAME_VERIFY_FAILED = -0x0201, /**< SSL validation of + hostname against + peer certificate + failed */ + AMQP_STATUS_SSL_PEER_VERIFY_FAILED = -0x0202, /**< SSL validation of peer + certificate failed. */ + AMQP_STATUS_SSL_CONNECTION_FAILED = -0x0203, /**< SSL handshake failed. */ + _AMQP_STATUS_SSL_NEXT_VALUE = -0x0204 /**< Internal value */ +} amqp_status_enum; + +/** + * AMQP delivery modes. + * Use these values for the #amqp_basic_properties_t::delivery_mode field. + * + * \since v0.5 + */ +typedef enum { + AMQP_DELIVERY_NONPERSISTENT = 1, /**< Non-persistent message */ + AMQP_DELIVERY_PERSISTENT = 2 /**< Persistent message */ +} amqp_delivery_mode_enum; + +AMQP_END_DECLS + +#include + +AMQP_BEGIN_DECLS + +/** + * Empty bytes structure + * + * \since v0.2 + */ +AMQP_PUBLIC_VARIABLE const amqp_bytes_t amqp_empty_bytes; + +/** + * Empty table structure + * + * \since v0.2 + */ +AMQP_PUBLIC_VARIABLE const amqp_table_t amqp_empty_table; + +/** + * Empty table array structure + * + * \since v0.2 + */ +AMQP_PUBLIC_VARIABLE const amqp_array_t amqp_empty_array; + +/* Compatibility macros for the above, to avoid the need to update + code written against earlier versions of librabbitmq. */ + +/** + * \def AMQP_EMPTY_BYTES + * + * Deprecated, use \ref amqp_empty_bytes instead + * + * \deprecated use \ref amqp_empty_bytes instead + * + * \since v0.1 + */ +#define AMQP_EMPTY_BYTES amqp_empty_bytes + +/** + * \def AMQP_EMPTY_TABLE + * + * Deprecated, use \ref amqp_empty_table instead + * + * \deprecated use \ref amqp_empty_table instead + * + * \since v0.1 + */ +#define AMQP_EMPTY_TABLE amqp_empty_table + +/** + * \def AMQP_EMPTY_ARRAY + * + * Deprecated, use \ref amqp_empty_array instead + * + * \deprecated use \ref amqp_empty_array instead + * + * \since v0.1 + */ +#define AMQP_EMPTY_ARRAY amqp_empty_array + +/** + * Initializes an amqp_pool_t memory allocation pool for use + * + * Readies an allocation pool for use. An amqp_pool_t + * must be initialized before use + * + * \param [in] pool the amqp_pool_t structure to initialize. + * Calling this function on a pool a pool that has + * already been initialized will result in undefined + * behavior + * \param [in] pagesize the unit size that the pool will allocate + * memory chunks in. Anything allocated against the pool + * with a requested size will be carved out of a block + * this size. Allocations larger than this will be + * allocated individually + * + * \sa recycle_amqp_pool(), empty_amqp_pool(), amqp_pool_alloc(), + * amqp_pool_alloc_bytes(), amqp_pool_t + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL init_amqp_pool(amqp_pool_t *pool, size_t pagesize); + +/** + * Recycles an amqp_pool_t memory allocation pool + * + * Recycles the space allocate by the pool + * + * This invalidates all allocations made against the pool before this call is + * made, any use of any allocations made before recycle_amqp_pool() is called + * will result in undefined behavior. + * + * Note: this may or may not release memory, to force memory to be released + * call empty_amqp_pool(). + * + * \param [in] pool the amqp_pool_t to recycle + * + * \sa recycle_amqp_pool(), empty_amqp_pool(), amqp_pool_alloc(), + * amqp_pool_alloc_bytes() + * + * \since v0.1 + * + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL recycle_amqp_pool(amqp_pool_t *pool); + +/** + * Empties an amqp memory pool + * + * Releases all memory associated with an allocation pool + * + * \param [in] pool the amqp_pool_t to empty + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL empty_amqp_pool(amqp_pool_t *pool); + +/** + * Allocates a block of memory from an amqp_pool_t memory pool + * + * Memory will be aligned on a 8-byte boundary. If a 0-length allocation is + * requested, a NULL pointer will be returned. + * + * \param [in] pool the allocation pool to allocate the memory from + * \param [in] amount the size of the allocation in bytes. + * \return a pointer to the memory block, or NULL if the allocation cannot + * be satisfied. + * + * \sa init_amqp_pool(), recycle_amqp_pool(), empty_amqp_pool(), + * amqp_pool_alloc_bytes() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void *AMQP_CALL amqp_pool_alloc(amqp_pool_t *pool, size_t amount); + +/** + * Allocates a block of memory from an amqp_pool_t to an amqp_bytes_t + * + * Memory will be aligned on a 8-byte boundary. If a 0-length allocation is + * requested, output.bytes = NULL. + * + * \param [in] pool the allocation pool to allocate the memory from + * \param [in] amount the size of the allocation in bytes + * \param [in] output the location to store the pointer. On success + * output.bytes will be set to the beginning of the buffer + * output.len will be set to amount + * On error output.bytes will be set to NULL and output.len + * set to 0 + * + * \sa init_amqp_pool(), recycle_amqp_pool(), empty_amqp_pool(), + * amqp_pool_alloc() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_pool_alloc_bytes(amqp_pool_t *pool, size_t amount, + amqp_bytes_t *output); + +/** + * Wraps a c string in an amqp_bytes_t + * + * Takes a string, calculates its length and creates an + * amqp_bytes_t that points to it. The string is not duplicated. + * + * For a given input cstr, The amqp_bytes_t output.bytes is the + * same as cstr, output.len is the length of the string not including + * the \0 terminator + * + * This function uses strlen() internally so cstr must be properly + * terminated + * + * \param [in] cstr the c string to wrap + * \return an amqp_bytes_t that describes the string + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_bytes_t AMQP_CALL amqp_cstring_bytes(char const *cstr); + +/** + * Duplicates an amqp_bytes_t buffer. + * + * The buffer is cloned and the contents copied. + * + * The memory associated with the output is allocated + * with amqp_bytes_malloc() and should be freed with + * amqp_bytes_free() + * + * \param [in] src + * \return a clone of the src + * + * \sa amqp_bytes_free(), amqp_bytes_malloc() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_bytes_t AMQP_CALL amqp_bytes_malloc_dup(amqp_bytes_t src); + +/** + * Allocates a amqp_bytes_t buffer + * + * Creates an amqp_bytes_t buffer of the specified amount, the buffer should be + * freed using amqp_bytes_free() + * + * \param [in] amount the size of the buffer in bytes + * \returns an amqp_bytes_t with amount bytes allocated. + * output.bytes will be set to NULL on error + * + * \sa amqp_bytes_free(), amqp_bytes_malloc_dup() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_bytes_t AMQP_CALL amqp_bytes_malloc(size_t amount); + +/** + * Frees an amqp_bytes_t buffer + * + * Frees a buffer allocated with amqp_bytes_malloc() or amqp_bytes_malloc_dup() + * + * Calling amqp_bytes_free on buffers not allocated with one + * of those two functions will result in undefined behavior + * + * \param [in] bytes the buffer to free + * + * \sa amqp_bytes_malloc(), amqp_bytes_malloc_dup() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_bytes_free(amqp_bytes_t bytes); + +/** + * Allocate and initialize a new amqp_connection_state_t object + * + * amqp_connection_state_t objects created with this function + * should be freed with amqp_destroy_connection() + * + * \returns an opaque pointer on success, NULL or 0 on failure. + * + * \sa amqp_destroy_connection() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_connection_state_t AMQP_CALL amqp_new_connection(void); + +/** + * Get the underlying socket descriptor for the connection + * + * \warning Use the socket returned from this function carefully, incorrect use + * of the socket outside of the library will lead to undefined behavior. + * Additionally rabbitmq-c may use the socket differently version-to-version, + * what may work in one version, may break in the next version. Be sure to + * throughly test any applications that use the socket returned by this + * function especially when using a newer version of rabbitmq-c + * + * \param [in] state the connection object + * \returns the socket descriptor if one has been set, -1 otherwise + * + * \sa amqp_tcp_socket_new(), amqp_ssl_socket_new(), amqp_socket_open() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_get_sockfd(amqp_connection_state_t state); + +/** + * Deprecated, use amqp_tcp_socket_new() or amqp_ssl_socket_new() + * + * \deprecated Use amqp_tcp_socket_new() or amqp_ssl_socket_new() + * + * Sets the socket descriptor associated with the connection. The socket + * should be connected to a broker, and should not be read to or written from + * before calling this function. A socket descriptor can be created and opened + * using amqp_open_socket() + * + * \param [in] state the connection object + * \param [in] sockfd the socket + * + * \sa amqp_open_socket(), amqp_tcp_socket_new(), amqp_ssl_socket_new() + * + * \since v0.1 + */ +AMQP_DEPRECATED(AMQP_PUBLIC_FUNCTION void AMQP_CALL + amqp_set_sockfd(amqp_connection_state_t state, int sockfd)); + +/** + * Tune client side parameters + * + * \warning This function may call abort() if the connection is in a certain + * state. As such it should probably not be called code outside the library. + * connection parameters should be specified when calling amqp_login() or + * amqp_login_with_properties() + * + * This function changes channel_max, frame_max, and heartbeat parameters, on + * the client side only. It does not try to renegotiate these parameters with + * the broker. Using this function will lead to unexpected results. + * + * \param [in] state the connection object + * \param [in] channel_max the maximum number of channels. + * The largest this can be is 65535 + * \param [in] frame_max the maximum size of an frame. + * The smallest this can be is 4096 + * The largest this can be is 2147483647 + * Unless you know what you're doing the recommended + * size is 131072 or 128KB + * \param [in] heartbeat the number of seconds between heartbeats + * + * \return AMQP_STATUS_OK on success, an amqp_status_enum value otherwise. + * Possible error codes include: + * - AMQP_STATUS_NO_MEMORY memory allocation failed. + * - AMQP_STATUS_TIMER_FAILURE the underlying system timer indicated it + * failed. + * + * \sa amqp_login(), amqp_login_with_properties() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_tune_connection(amqp_connection_state_t state, + int channel_max, int frame_max, + int heartbeat); + +/** + * Get the maximum number of channels the connection can handle + * + * The maximum number of channels is set when connection negotiation takes + * place in amqp_login() or amqp_login_with_properties(). + * + * \param [in] state the connection object + * \return the maximum number of channels. 0 if there is no limit + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_get_channel_max(amqp_connection_state_t state); + +/** + * Get the maximum size of an frame the connection can handle + * + * The maximum size of an frame is set when connection negotiation takes + * place in amqp_login() or amqp_login_with_properties(). + * + * \param [in] state the connection object + * \return the maximum size of an frame. + * + * \since v0.6 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_get_frame_max(amqp_connection_state_t state); + +/** + * Get the number of seconds between heartbeats of the connection + * + * The number of seconds between heartbeats is set when connection + * negotiation takes place in amqp_login() or amqp_login_with_properties(). + * + * \param [in] state the connection object + * \return the number of seconds between heartbeats. + * + * \since v0.6 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_get_heartbeat(amqp_connection_state_t state); + +/** + * Destroys an amqp_connection_state_t object + * + * Destroys a amqp_connection_state_t object that was created with + * amqp_new_connection(). If the connection with the broker is open, it will be + * implicitly closed with a reply code of 200 (success). Any memory that + * would be freed with amqp_maybe_release_buffers() or + * amqp_maybe_release_buffers_on_channel() will be freed, and use of that + * memory will caused undefined behavior. + * + * \param [in] state the connection object + * \return AMQP_STATUS_OK on success. amqp_status_enum value failure + * + * \sa amqp_new_connection() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_destroy_connection(amqp_connection_state_t state); + +/** + * Process incoming data + * + * \warning This is a low-level function intended for those who want to + * have greater control over input and output over the socket from the + * broker. Correctly using this function requires in-depth knowledge of AMQP + * and rabbitmq-c. + * + * For a given buffer of data received from the broker, decode the first + * frame in the buffer. If more than one frame is contained in the input buffer + * the return value will be less than the received_data size, the caller should + * adjust received_data buffer descriptor to point to the beginning of the + * buffer + the return value. + * + * \param [in] state the connection object + * \param [in] received_data a buffer of data received from the broker. The + * function will return the number of bytes of the buffer it used. The + * function copies these bytes to an internal buffer: this part of the buffer + * may be reused after this function successfully completes. + * \param [in,out] decoded_frame caller should pass in a pointer to an + * amqp_frame_t struct. If there is enough data in received_data for a + * complete frame, decoded_frame->frame_type will be set to something OTHER + * than 0. decoded_frame may contain members pointing to memory owned by + * the state object. This memory can be recycled with + * amqp_maybe_release_buffers() or amqp_maybe_release_buffers_on_channel(). + * \return number of bytes consumed from received_data or 0 if a 0-length + * buffer was passed. A negative return value indicates failure. Possible + * errors: + * - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely + * in an indeterminate state making recovery unlikely. Client should note the + * error and terminate the application + * - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection + * should be shutdown immediately + * - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the + * broker. This is likely a protocol error and the connection should be + * shutdown immediately + * - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class + * was received from the broker. This is likely a protocol error and the + * connection should be shutdown immediately + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_handle_input(amqp_connection_state_t state, + amqp_bytes_t received_data, + amqp_frame_t *decoded_frame); + +/** + * Check to see if connection memory can be released + * + * \deprecated This function is deprecated in favor of + * amqp_maybe_release_buffers() or amqp_maybe_release_buffers_on_channel() + * + * Checks the state of an amqp_connection_state_t object to see if + * amqp_release_buffers() can be called successfully. + * + * \param [in] state the connection object + * \returns TRUE if the buffers can be released FALSE otherwise + * + * \sa amqp_release_buffers() amqp_maybe_release_buffers() + * amqp_maybe_release_buffers_on_channel() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t AMQP_CALL amqp_release_buffers_ok(amqp_connection_state_t state); + +/** + * Release amqp_connection_state_t owned memory + * + * \deprecated This function is deprecated in favor of + * amqp_maybe_release_buffers() or amqp_maybe_release_buffers_on_channel() + * + * \warning caller should ensure amqp_release_buffers_ok() returns true before + * calling this function. Failure to do so may result in abort() being called. + * + * Release memory owned by the amqp_connection_state_t for reuse by the + * library. Use of any memory returned by the library before this function is + * called will result in undefined behavior. + * + * \note internally rabbitmq-c tries to reuse memory when possible. As a result + * its possible calling this function may not have a noticeable effect on + * memory usage. + * + * \param [in] state the connection object + * + * \sa amqp_release_buffers_ok() amqp_maybe_release_buffers() + * amqp_maybe_release_buffers_on_channel() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_release_buffers(amqp_connection_state_t state); + +/** + * Release amqp_connection_state_t owned memory + * + * Release memory owned by the amqp_connection_state_t object related to any + * channel, allowing reuse by the library. Use of any memory returned by the + * library before this function is called with result in undefined behavior. + * + * \note internally rabbitmq-c tries to reuse memory when possible. As a result + * its possible calling this function may not have a noticeable effect on + * memory usage. + * + * \param [in] state the connection object + * + * \sa amqp_maybe_release_buffers_on_channel() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_maybe_release_buffers(amqp_connection_state_t state); + +/** + * Release amqp_connection_state_t owned memory related to a channel + * + * Release memory owned by the amqp_connection_state_t object related to the + * specified channel, allowing reuse by the library. Use of any memory returned + * the library for a specific channel will result in undefined behavior. + * + * \note internally rabbitmq-c tries to reuse memory when possible. As a result + * its possible calling this function may not have a noticeable effect on + * memory usage. + * + * \param [in] state the connection object + * \param [in] channel the channel specifier for which memory should be + * released. Note that the library does not care about the state of the + * channel when calling this function + * + * \sa amqp_maybe_release_buffers() + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_maybe_release_buffers_on_channel( + amqp_connection_state_t state, amqp_channel_t channel); + +/** + * Send a frame to the broker + * + * \param [in] state the connection object + * \param [in] frame the frame to send to the broker + * \return AMQP_STATUS_OK on success, an amqp_status_enum value on error. + * Possible error codes: + * - AMQP_STATUS_BAD_AMQP_DATA the serialized form of the method or + * properties was too large to fit in a single AMQP frame, or the + * method contains an invalid value. The frame was not sent. + * - AMQP_STATUS_TABLE_TOO_BIG the serialized form of an amqp_table_t is + * too large to fit in a single AMQP frame. Frame was not sent. + * - AMQP_STATUS_UNKNOWN_METHOD an invalid method type was passed in + * - AMQP_STATUS_UNKNOWN_CLASS an invalid properties type was passed in + * - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. The frame + * was sent + * - AMQP_STATUS_SOCKET_ERROR + * - AMQP_STATUS_SSL_ERROR + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_send_frame(amqp_connection_state_t state, + amqp_frame_t const *frame); + +/** + * Compare two table entries + * + * Works just like strcmp(), comparing two the table keys, datatype, then values + * + * \param [in] entry1 the entry on the left + * \param [in] entry2 the entry on the right + * \return 0 if entries are equal, 0 < if left is greater, 0 > if right is + * greater + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_table_entry_cmp(void const *entry1, void const *entry2); + +/** + * Open a socket to a remote host + * + * \deprecated This function is deprecated in favor of amqp_socket_open() + * + * Looks up the hostname, then attempts to open a socket to the host using + * the specified portnumber. It also sets various options on the socket to + * improve performance and correctness. + * + * \param [in] hostname this can be a hostname or IP address. + * Both IPv4 and IPv6 are acceptable + * \param [in] portnumber the port to connect on. RabbitMQ brokers + * listen on port 5672, and 5671 for SSL + * \return a positive value indicates success and is the sockfd. A negative + * value (see amqp_status_enum)is returned on failure. Possible error codes: + * - AMQP_STATUS_TCP_SOCKETLIB_INIT_ERROR Initialization of underlying socket + * library failed. + * - AMQP_STATUS_HOSTNAME_RESOLUTION_FAILED hostname lookup failed. + * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. errno or + * WSAGetLastError() may return more useful information. + * + * \note IPv6 support was added in v0.3 + * + * \sa amqp_socket_open() amqp_set_sockfd() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_open_socket(char const *hostname, int portnumber); + +/** + * Send initial AMQP header to the broker + * + * \warning this is a low level function intended for those who want to + * interact with the broker at a very low level. Use of this function without + * understanding what it does will result in AMQP protocol errors. + * + * This function sends the AMQP protocol header to the broker. + * + * \param [in] state the connection object + * \return AMQP_STATUS_OK on success, a negative value on failure. Possible + * error codes: + * - AMQP_STATUS_CONNECTION_CLOSED the connection to the broker was closed. + * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. It is likely the + * underlying socket has been closed. errno or WSAGetLastError() may provide + * further information. + * - AMQP_STATUS_SSL_ERROR a SSL error occurred. The connection to the broker + * was closed. + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_send_header(amqp_connection_state_t state); + +/** + * Checks to see if there are any incoming frames ready to be read + * + * Checks to see if there are any amqp_frame_t objects buffered by the + * amqp_connection_state_t object. Having one or more frames buffered means + * that amqp_simple_wait_frame() or amqp_simple_wait_frame_noblock() will + * return a frame without potentially blocking on a read() call. + * + * \param [in] state the connection object + * \return TRUE if there are frames enqueued, FALSE otherwise + * + * \sa amqp_simple_wait_frame() amqp_simple_wait_frame_noblock() + * amqp_data_in_buffer() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t AMQP_CALL amqp_frames_enqueued(amqp_connection_state_t state); + +/** + * Read a single amqp_frame_t + * + * Waits for the next amqp_frame_t frame to be read from the broker. + * This function has the potential to block for a long time in the case of + * waiting for a basic.deliver method frame from the broker. + * + * The library may buffer frames. When an amqp_connection_state_t object + * has frames buffered calling amqp_simple_wait_frame() will return an + * amqp_frame_t without entering a blocking read(). You can test to see if + * an amqp_connection_state_t object has frames buffered by calling the + * amqp_frames_enqueued() function. + * + * The library has a socket read buffer. When there is data in an + * amqp_connection_state_t read buffer, amqp_simple_wait_frame() may return an + * amqp_frame_t without entering a blocking read(). You can test to see if an + * amqp_connection_state_t object has data in its read buffer by calling the + * amqp_data_in_buffer() function. + * + * \param [in] state the connection object + * \param [out] decoded_frame the frame + * \return AMQP_STATUS_OK on success, an amqp_status_enum value + * is returned otherwise. Possible errors include: + * - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely + * in an indeterminate state making recovery unlikely. Client should note the + * error and terminate the application + * - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection + * should be shutdown immediately + * - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the + * broker. This is likely a protocol error and the connection should be + * shutdown immediately + * - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class + * was received from the broker. This is likely a protocol error and the + * connection should be shutdown immediately + * - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat + * from the broker. The connection has been closed. + * - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. + * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has + * been closed + * - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has + * been closed. + * + * \sa amqp_simple_wait_frame_noblock() amqp_frames_enqueued() + * amqp_data_in_buffer() + * + * \note as of v0.4.0 this function will no longer return heartbeat frames + * when enabled by specifying a non-zero heartbeat value in amqp_login(). + * Heartbeating is handled internally by the library. + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_simple_wait_frame(amqp_connection_state_t state, + amqp_frame_t *decoded_frame); + +/** + * Read a single amqp_frame_t with a timeout. + * + * Waits for the next amqp_frame_t frame to be read from the broker, up to + * a timespan specified by tv. The function will return AMQP_STATUS_TIMEOUT + * if the timeout is reached. The tv value is not modified by the function. + * + * If a 0 timeval is specified, the function behaves as if its non-blocking: it + * will test to see if a frame can be read from the broker, and return + * immediately. + * + * If NULL is passed in for tv, the function will behave like + * amqp_simple_wait_frame() and block until a frame is received from the broker + * + * The library may buffer frames. When an amqp_connection_state_t object + * has frames buffered calling amqp_simple_wait_frame_noblock() will return an + * amqp_frame_t without entering a blocking read(). You can test to see if an + * amqp_connection_state_t object has frames buffered by calling the + * amqp_frames_enqueued() function. + * + * The library has a socket read buffer. When there is data in an + * amqp_connection_state_t read buffer, amqp_simple_wait_frame_noblock() may + * return + * an amqp_frame_t without entering a blocking read(). You can test to see if an + * amqp_connection_state_t object has data in its read buffer by calling the + * amqp_data_in_buffer() function. + * + * \note This function does not return heartbeat frames. When enabled, + * heartbeating is handed internally internally by the library. + * + * \param [in,out] state the connection object + * \param [out] decoded_frame the frame + * \param [in] tv the maximum time to wait for a frame to be read. Setting + * tv->tv_sec = 0 and tv->tv_usec = 0 will do a non-blocking read. Specifying + * NULL for tv will make the function block until a frame is read. + * \return AMQP_STATUS_OK on success. An amqp_status_enum value is returned + * otherwise. Possible errors include: + * - AMQP_STATUS_TIMEOUT the timeout was reached while waiting for a frame + * from the broker. + * - AMQP_STATUS_INVALID_PARAMETER the tv parameter contains an invalid value. + * - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely + * in an indeterminate state making recovery unlikely. Client should note the + * error and terminate the application + * - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection + * should be shutdown immediately + * - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the + * broker. This is likely a protocol error and the connection should be + * shutdown immediately + * - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class + * was received from the broker. This is likely a protocol error and the + * connection should be shutdown immediately + * - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat + * from the broker. The connection has been closed. + * - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. + * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has + * been closed + * - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has + * been closed. + * + * \sa amqp_simple_wait_frame() amqp_frames_enqueued() amqp_data_in_buffer() + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_simple_wait_frame_noblock(amqp_connection_state_t state, + amqp_frame_t *decoded_frame, + struct timeval *tv); + +/** + * Waits for a specific method from the broker + * + * \warning You probably don't want to use this function. If this function + * doesn't receive exactly the frame requested it closes the whole connection. + * + * Waits for a single method on a channel from the broker. + * If a frame is received that does not match expected_channel + * or expected_method the program will abort + * + * \param [in] state the connection object + * \param [in] expected_channel the channel that the method should be delivered + * on + * \param [in] expected_method the method to wait for + * \param [out] output the method + * \returns AMQP_STATUS_OK on success. An amqp_status_enum value is returned + * otherwise. Possible errors include: + * - AMQP_STATUS_WRONG_METHOD a frame containing the wrong method, wrong frame + * type or wrong channel was received. The connection is closed. + * - AMQP_STATUS_NO_MEMORY failure in allocating memory. The library is likely + * in an indeterminate state making recovery unlikely. Client should note the + * error and terminate the application + * - AMQP_STATUS_BAD_AMQP_DATA bad AMQP data was received. The connection + * should be shutdown immediately + * - AMQP_STATUS_UNKNOWN_METHOD: an unknown method was received from the + * broker. This is likely a protocol error and the connection should be + * shutdown immediately + * - AMQP_STATUS_UNKNOWN_CLASS: a properties frame with an unknown class + * was received from the broker. This is likely a protocol error and the + * connection should be shutdown immediately + * - AMQP_STATUS_HEARTBEAT_TIMEOUT timed out while waiting for heartbeat + * from the broker. The connection has been closed. + * - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. + * - AMQP_STATUS_SOCKET_ERROR a socket error occurred. The connection has + * been closed + * - AMQP_STATUS_SSL_ERROR a SSL socket error occurred. The connection has + * been closed. + * + * \since v0.1 + */ + +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_simple_wait_method(amqp_connection_state_t state, + amqp_channel_t expected_channel, + amqp_method_number_t expected_method, + amqp_method_t *output); + +/** + * Sends a method to the broker + * + * This is a thin wrapper around amqp_send_frame(), providing a way to send + * a method to the broker on a specified channel. + * + * \param [in] state the connection object + * \param [in] channel the channel object + * \param [in] id the method number + * \param [in] decoded the method object + * \returns AMQP_STATUS_OK on success, an amqp_status_enum value otherwise. + * Possible errors include: + * - AMQP_STATUS_BAD_AMQP_DATA the serialized form of the method or + * properties was too large to fit in a single AMQP frame, or the + * method contains an invalid value. The frame was not sent. + * - AMQP_STATUS_TABLE_TOO_BIG the serialized form of an amqp_table_t is + * too large to fit in a single AMQP frame. Frame was not sent. + * - AMQP_STATUS_UNKNOWN_METHOD an invalid method type was passed in + * - AMQP_STATUS_UNKNOWN_CLASS an invalid properties type was passed in + * - AMQP_STATUS_TIMER_FAILURE system timer indicated failure. The frame + * was sent + * - AMQP_STATUS_SOCKET_ERROR + * - AMQP_STATUS_SSL_ERROR + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_send_method(amqp_connection_state_t state, + amqp_channel_t channel, amqp_method_number_t id, + void *decoded); + +/** + * Sends a method to the broker and waits for a method response + * + * \param [in] state the connection object + * \param [in] channel the channel object + * \param [in] request_id the method number of the request + * \param [in] expected_reply_ids a 0 terminated array of expected response + * method numbers + * \param [in] decoded_request_method the method to be sent to the broker + * \return a amqp_rpc_reply_t: + * - r.reply_type == AMQP_RESPONSE_NORMAL. RPC completed successfully + * - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an + * exception: + * - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception + * occurred, cast r.reply.decoded to amqp_channel_close_t* to see details + * of the exception. The client should amqp_send_method() a + * amqp_channel_close_ok_t. The channel must be re-opened before it + * can be used again. Any resources associated with the channel + * (auto-delete exchanges, auto-delete queues, consumers) are invalid + * and must be recreated before attempting to use them again. + * - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception + * occurred, cast r.reply.decoded to amqp_connection_close_t* to see + * details of the exception. The client amqp_send_method() a + * amqp_connection_close_ok_t and disconnect from the broker. + * - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. An exception occurred + * within the library. Examine r.library_error and compare it against + * amqp_status_enum values to determine the error. + * + * \sa amqp_simple_rpc_decoded() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_simple_rpc( + amqp_connection_state_t state, amqp_channel_t channel, + amqp_method_number_t request_id, amqp_method_number_t *expected_reply_ids, + void *decoded_request_method); + +/** + * Sends a method to the broker and waits for a method response + * + * \param [in] state the connection object + * \param [in] channel the channel object + * \param [in] request_id the method number of the request + * \param [in] reply_id the method number expected in response + * \param [in] decoded_request_method the request method + * \return a pointer to the method returned from the broker, or NULL on error. + * On error amqp_get_rpc_reply() will return an amqp_rpc_reply_t with + * details on the error that occurred. + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +void *AMQP_CALL amqp_simple_rpc_decoded(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_method_number_t request_id, + amqp_method_number_t reply_id, + void *decoded_request_method); + +/** + * Get the last global amqp_rpc_reply + * + * The API methods corresponding to most synchronous AMQP methods + * return a pointer to the decoded method result. Upon error, they + * return NULL, and we need some way of discovering what, if anything, + * went wrong. amqp_get_rpc_reply() returns the most recent + * amqp_rpc_reply_t instance corresponding to such an API operation + * for the given connection. + * + * Only use it for operations that do not themselves return + * amqp_rpc_reply_t; operations that do return amqp_rpc_reply_t + * generally do NOT update this per-connection-global amqp_rpc_reply_t + * instance. + * + * \param [in] state the connection object + * \return the most recent amqp_rpc_reply_t: + * - r.reply_type == AMQP_RESPONSE_NORMAL. RPC completed successfully + * - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an + * exception: + * - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception + * occurred, cast r.reply.decoded to amqp_channel_close_t* to see details + * of the exception. The client should amqp_send_method() a + * amqp_channel_close_ok_t. The channel must be re-opened before it + * can be used again. Any resources associated with the channel + * (auto-delete exchanges, auto-delete queues, consumers) are invalid + * and must be recreated before attempting to use them again. + * - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception + * occurred, cast r.reply.decoded to amqp_connection_close_t* to see + * details of the exception. The client amqp_send_method() a + * amqp_connection_close_ok_t and disconnect from the broker. + * - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. An exception occurred + * within the library. Examine r.library_error and compare it against + * amqp_status_enum values to determine the error. + * + * \sa amqp_simple_rpc_decoded() + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_get_rpc_reply(amqp_connection_state_t state); + +/** + * Login to the broker + * + * After using amqp_open_socket and amqp_set_sockfd, call + * amqp_login to complete connecting to the broker + * + * \param [in] state the connection object + * \param [in] vhost the virtual host to connect to on the broker. The default + * on most brokers is "/" + * \param [in] channel_max the limit for number of channels for the connection. + * 0 means no limit, and is a good default + * (AMQP_DEFAULT_MAX_CHANNELS) + * Note that the maximum number of channels the protocol supports + * is 65535 (2^16, with the 0-channel reserved). The server can + * set a lower channel_max and then the client will use the lowest + * of the two + * \param [in] frame_max the maximum size of an AMQP frame on the wire to + * request of the broker for this connection. 4096 is the minimum + * size, 2^31-1 is the maximum, a good default is 131072 (128KB), + * or AMQP_DEFAULT_FRAME_SIZE + * \param [in] heartbeat the number of seconds between heartbeat frames to + * request of the broker. A value of 0 disables heartbeats. + * Note rabbitmq-c only has partial support for heartbeats, as of + * v0.4.0 they are only serviced during amqp_basic_publish() and + * amqp_simple_wait_frame()/amqp_simple_wait_frame_noblock() + * \param [in] sasl_method the SASL method to authenticate with the broker. + * followed by the authentication information. The following SASL + * methods are implemented: + * - AMQP_SASL_METHOD_PLAIN, the AMQP_SASL_METHOD_PLAIN argument + * should be followed by two arguments in this order: + * const char* username, and const char* password. + * - AMQP_SASL_METHOD_EXTERNAL, the AMQP_SASL_METHOD_EXTERNAL + * argument should be followed one argument: + * const char* identity. + * \return amqp_rpc_reply_t indicating success or failure. + * - r.reply_type == AMQP_RESPONSE_NORMAL. Login completed successfully + * - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. In most cases errors + * from the broker when logging in will be represented by the broker closing + * the socket. In this case r.library_error will be set to + * AMQP_STATUS_CONNECTION_CLOSED. This error can represent a number of + * error conditions including: invalid vhost, authentication failure. + * - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an + * exception: + * - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception + * occurred, cast r.reply.decoded to amqp_channel_close_t* to see details + * of the exception. The client should amqp_send_method() a + * amqp_channel_close_ok_t. The channel must be re-opened before it + * can be used again. Any resources associated with the channel + * (auto-delete exchanges, auto-delete queues, consumers) are invalid + * and must be recreated before attempting to use them again. + * - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception + * occurred, cast r.reply.decoded to amqp_connection_close_t* to see + * details of the exception. The client amqp_send_method() a + * amqp_connection_close_ok_t and disconnect from the broker. + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_login(amqp_connection_state_t state, + char const *vhost, int channel_max, + int frame_max, int heartbeat, + amqp_sasl_method_enum sasl_method, ...); + +/** + * Login to the broker passing a properties table + * + * This function is similar to amqp_login() and differs in that it provides a + * way to pass client properties to the broker. This is commonly used to + * negotiate newer protocol features as they are supported by the broker. + * + * \param [in] state the connection object + * \param [in] vhost the virtual host to connect to on the broker. The default + * on most brokers is "/" + * \param [in] channel_max the limit for the number of channels for the + * connection. + * 0 means no limit, and is a good default + * (AMQP_DEFAULT_MAX_CHANNELS) + * Note that the maximum number of channels the protocol supports + * is 65535 (2^16, with the 0-channel reserved). The server can + * set a lower channel_max and then the client will use the lowest + * of the two + * \param [in] frame_max the maximum size of an AMQP frame ont he wire to + * request of the broker for this connection. 4096 is the minimum + * size, 2^31-1 is the maximum, a good default is 131072 (128KB), + * or AMQP_DEFAULT_FRAME_SIZE + * \param [in] heartbeat the number of seconds between heartbeat frame to + * request of the broker. A value of 0 disables heartbeats. + * Note rabbitmq-c only has partial support for hearts, as of + * v0.4.0 heartbeats are only serviced during amqp_basic_publish(), + * and amqp_simple_wait_frame()/amqp_simple_wait_frame_noblock() + * \param [in] properties a table of properties to send the broker. + * \param [in] sasl_method the SASL method to authenticate with the broker + * followed by the authentication information. The following SASL + * methods are implemented: + * - AMQP_SASL_METHOD_PLAIN, the AMQP_SASL_METHOD_PLAIN argument + * should be followed by two arguments in this order: + * const char* username, and const char* password. + * - AMQP_SASL_METHOD_EXTERNAL, the AMQP_SASL_METHOD_EXTERNAL + * argument should be followed one argument: + * const char* identity. + * \return amqp_rpc_reply_t indicating success or failure. + * - r.reply_type == AMQP_RESPONSE_NORMAL. Login completed successfully + * - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. In most cases errors + * from the broker when logging in will be represented by the broker closing + * the socket. In this case r.library_error will be set to + * AMQP_STATUS_CONNECTION_CLOSED. This error can represent a number of + * error conditions including: invalid vhost, authentication failure. + * - r.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION. The broker returned an + * exception: + * - If r.reply.id == AMQP_CHANNEL_CLOSE_METHOD a channel exception + * occurred, cast r.reply.decoded to amqp_channel_close_t* to see details + * of the exception. The client should amqp_send_method() a + * amqp_channel_close_ok_t. The channel must be re-opened before it + * can be used again. Any resources associated with the channel + * (auto-delete exchanges, auto-delete queues, consumers) are invalid + * and must be recreated before attempting to use them again. + * - If r.reply.id == AMQP_CONNECTION_CLOSE_METHOD a connection exception + * occurred, cast r.reply.decoded to amqp_connection_close_t* to see + * details of the exception. The client amqp_send_method() a + * amqp_connection_close_ok_t and disconnect from the broker. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_login_with_properties( + amqp_connection_state_t state, char const *vhost, int channel_max, + int frame_max, int heartbeat, const amqp_table_t *properties, + amqp_sasl_method_enum sasl_method, ...); + +struct amqp_basic_properties_t_; + +/** + * Publish a message to the broker + * + * Publish a message on an exchange with a routing key. + * + * Note that at the AMQ protocol level basic.publish is an async method: + * this means error conditions that occur on the broker (such as publishing to + * a non-existent exchange) will not be reflected in the return value of this + * function. + * + * \param [in] state the connection object + * \param [in] channel the channel identifier + * \param [in] exchange the exchange on the broker to publish to + * \param [in] routing_key the routing key to use when publishing the message + * \param [in] mandatory indicate to the broker that the message MUST be routed + * to a queue. If the broker cannot do this it should respond with + * a basic.return method. + * \param [in] immediate indicate to the broker that the message MUST be + * delivered to a consumer immediately. If the broker cannot do this + * it should respond with a basic.return method. + * \param [in] properties the properties associated with the message + * \param [in] body the message body + * \return AMQP_STATUS_OK on success, amqp_status_enum value on failure. Note + * that basic.publish is an async method, the return value from this + * function only indicates that the message data was successfully + * transmitted to the broker. It does not indicate failures that occur + * on the broker, such as publishing to a non-existent exchange. + * Possible error values: + * - AMQP_STATUS_TIMER_FAILURE: system timer facility returned an error + * the message was not sent. + * - AMQP_STATUS_HEARTBEAT_TIMEOUT: connection timed out waiting for a + * heartbeat from the broker. The message was not sent. + * - AMQP_STATUS_NO_MEMORY: memory allocation failed. The message was + * not sent. + * - AMQP_STATUS_TABLE_TOO_BIG: a table in the properties was too large + * to fit in a single frame. Message was not sent. + * - AMQP_STATUS_CONNECTION_CLOSED: the connection was closed. + * - AMQP_STATUS_SSL_ERROR: a SSL error occurred. + * - AMQP_STATUS_TCP_ERROR: a TCP error occurred. errno or + * WSAGetLastError() may provide more information + * + * Note: this function does heartbeat processing as of v0.4.0 + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_basic_publish( + amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_boolean_t mandatory, + amqp_boolean_t immediate, struct amqp_basic_properties_t_ const *properties, + amqp_bytes_t body); + +/** + * Closes an channel + * + * \param [in] state the connection object + * \param [in] channel the channel identifier + * \param [in] code the reason for closing the channel, AMQP_REPLY_SUCCESS is a + * good default + * \return amqp_rpc_reply_t indicating success or failure + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_channel_close(amqp_connection_state_t state, + amqp_channel_t channel, int code); + +/** + * Closes the entire connection + * + * Implicitly closes all channels and informs the broker the connection + * is being closed, after receiving acknowledgment from the broker it closes + * the socket. + * + * \param [in] state the connection object + * \param [in] code the reason code for closing the connection. + * AMQP_REPLY_SUCCESS is a good default. + * \return amqp_rpc_reply_t indicating the result + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_connection_close(amqp_connection_state_t state, + int code); + +/** + * Acknowledges a message + * + * Does a basic.ack on a received message + * + * \param [in] state the connection object + * \param [in] channel the channel identifier + * \param [in] delivery_tag the delivery tag of the message to be ack'd + * \param [in] multiple if true, ack all messages up to this delivery tag, if + * false ack only this delivery tag + * \return 0 on success, 0 > on failing to send the ack to the broker. + * this will not indicate failure if something goes wrong on the + * broker + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_basic_ack(amqp_connection_state_t state, + amqp_channel_t channel, uint64_t delivery_tag, + amqp_boolean_t multiple); + +/** + * Do a basic.get + * + * Synchonously polls the broker for a message in a queue, and + * retrieves the message if a message is in the queue. + * + * \param [in] state the connection object + * \param [in] channel the channel identifier to use + * \param [in] queue the queue name to retrieve from + * \param [in] no_ack if true the message is automatically ack'ed + * if false amqp_basic_ack should be called once the message + * retrieved has been processed + * \return amqp_rpc_reply indicating success or failure + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_basic_get(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_bytes_t queue, + amqp_boolean_t no_ack); + +/** + * Do a basic.reject + * + * Actively reject a message that has been delivered + * + * \param [in] state the connection object + * \param [in] channel the channel identifier + * \param [in] delivery_tag the delivery tag of the message to reject + * \param [in] requeue indicate to the broker whether it should requeue the + * message or just discard it. + * \return 0 on success, 0 > on failing to send the reject method to the broker. + * This will not indicate failure if something goes wrong on the + * broker. + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_basic_reject(amqp_connection_state_t state, + amqp_channel_t channel, uint64_t delivery_tag, + amqp_boolean_t requeue); + +/** + * Do a basic.nack + * + * Actively reject a message, this has the same effect as amqp_basic_reject() + * however, amqp_basic_nack() can negatively acknowledge multiple messages with + * one call much like amqp_basic_ack() can acknowledge mutliple messages with + * one call. + * + * \param [in] state the connection object + * \param [in] channel the channel identifier + * \param [in] delivery_tag the delivery tag of the message to reject + * \param [in] multiple if set to 1 negatively acknowledge all unacknowledged + * messages on this channel. + * \param [in] requeue indicate to the broker whether it should requeue the + * message or dead-letter it. + * \return AMQP_STATUS_OK on success, an amqp_status_enum value otherwise. + * + * \since v0.5.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_basic_nack(amqp_connection_state_t state, + amqp_channel_t channel, uint64_t delivery_tag, + amqp_boolean_t multiple, amqp_boolean_t requeue); +/** + * Check to see if there is data left in the receive buffer + * + * Can be used to see if there is data still in the buffer, if so + * calling amqp_simple_wait_frame will not immediately enter a + * blocking read. + * + * \param [in] state the connection object + * \return true if there is data in the recieve buffer, false otherwise + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t AMQP_CALL amqp_data_in_buffer(amqp_connection_state_t state); + +/** + * Get the error string for the given error code. + * + * \deprecated This function has been deprecated in favor of + * \ref amqp_error_string2() which returns statically allocated + * string which do not need to be freed by the caller. + * + * The returned string resides on the heap; the caller is responsible + * for freeing it. + * + * \param [in] err return error code + * \return the error string + * + * \since v0.1 + */ +AMQP_DEPRECATED( + AMQP_PUBLIC_FUNCTION char *AMQP_CALL amqp_error_string(int err)); + +/** + * Get the error string for the given error code. + * + * Get an error string associated with an error code. The string is statically + * allocated and does not need to be freed + * + * \param [in] err the error code + * \return the error string + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +const char *AMQP_CALL amqp_error_string2(int err); + +/** + * Deserialize an amqp_table_t from AMQP wireformat + * + * This is an internal function and is not typically used by + * client applications + * + * \param [in] encoded the buffer containing the serialized data + * \param [in] pool memory pool used to allocate the table entries from + * \param [in] output the amqp_table_t structure to fill in. Any existing + * entries will be erased + * \param [in,out] offset The offset into the encoded buffer to start + * reading the serialized table. It will be updated + * by this function to end of the table + * \return AMQP_STATUS_OK on success, an amqp_status_enum value on failure + * Possible error codes: + * - AMQP_STATUS_NO_MEMORY out of memory + * - AMQP_STATUS_BAD_AMQP_DATA invalid wireformat + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_decode_table(amqp_bytes_t encoded, amqp_pool_t *pool, + amqp_table_t *output, size_t *offset); + +/** + * Serializes an amqp_table_t to the AMQP wireformat + * + * This is an internal function and is not typically used by + * client applications + * + * \param [in] encoded the buffer where to serialize the table to + * \param [in] input the amqp_table_t to serialize + * \param [in,out] offset The offset into the encoded buffer to start + * writing the serialized table. It will be updated + * by this function to where writing left off + * \return AMQP_STATUS_OK on success, an amqp_status_enum value on failure + * Possible error codes: + * - AMQP_STATUS_TABLE_TOO_BIG the serialized form is too large for the + * buffer + * - AMQP_STATUS_BAD_AMQP_DATA invalid table + * + * \since v0.1 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_encode_table(amqp_bytes_t encoded, amqp_table_t *input, + size_t *offset); + +/** + * Create a deep-copy of an amqp_table_t object + * + * Creates a deep-copy of an amqp_table_t object, using the provided pool + * object to allocate the necessary memory. This memory can be freed later by + * call recycle_amqp_pool(), or empty_amqp_pool() + * + * \param [in] original the table to copy + * \param [in,out] clone the table to copy to + * \param [in] pool the initialized memory pool to do allocations for the table + * from + * \return AMQP_STATUS_OK on success, amqp_status_enum value on failure. + * Possible error values: + * - AMQP_STATUS_NO_MEMORY - memory allocation failure. + * - AMQP_STATUS_INVALID_PARAMETER - invalid table (e.g., no key name) + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_table_clone(const amqp_table_t *original, + amqp_table_t *clone, amqp_pool_t *pool); + +/** + * A message object + * + * \since v0.4.0 + */ +typedef struct amqp_message_t_ { + amqp_basic_properties_t properties; /**< message properties */ + amqp_bytes_t body; /**< message body */ + amqp_pool_t pool; /**< pool used to allocate properties */ +} amqp_message_t; + +/** + * Reads the next message on a channel + * + * Reads a complete message (header + body) on a specified channel. This + * function is intended to be used with amqp_basic_get() or when an + * AMQP_BASIC_DELIVERY_METHOD method is received. + * + * \param [in,out] state the connection object + * \param [in] channel the channel on which to read the message from + * \param [in,out] message a pointer to a amqp_message_t object. Caller should + * call amqp_message_destroy() when it is done using the + * fields in the message object. The caller is responsible for + * allocating/destroying the amqp_message_t object itself. + * \param [in] flags pass in 0. Currently unused. + * \returns a amqp_rpc_reply_t object. ret.reply_type == AMQP_RESPONSE_NORMAL on + * success. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_read_message(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_message_t *message, + int flags); + +/** + * Frees memory associated with a amqp_message_t allocated in amqp_read_message + * + * \param [in] message + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_destroy_message(amqp_message_t *message); + +/** + * Envelope object + * + * \since v0.4.0 + */ +typedef struct amqp_envelope_t_ { + amqp_channel_t channel; /**< channel message was delivered on */ + amqp_bytes_t + consumer_tag; /**< the consumer tag the message was delivered to */ + uint64_t delivery_tag; /**< the messages delivery tag */ + amqp_boolean_t redelivered; /**< flag indicating whether this message is being + redelivered */ + amqp_bytes_t exchange; /**< exchange this message was published to */ + amqp_bytes_t + routing_key; /**< the routing key this message was published with */ + amqp_message_t message; /**< the message */ +} amqp_envelope_t; + +/** + * Wait for and consume a message + * + * Waits for a basic.deliver method on any channel, upon receipt of + * basic.deliver it reads that message, and returns. If any other method is + * received before basic.deliver, this function will return an amqp_rpc_reply_t + * with ret.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION, and + * ret.library_error == AMQP_STATUS_UNEXPECTED_STATE. The caller should then + * call amqp_simple_wait_frame() to read this frame and take appropriate action. + * + * This function should be used after starting a consumer with the + * amqp_basic_consume() function + * + * \param [in,out] state the connection object + * \param [in,out] envelope a pointer to a amqp_envelope_t object. Caller + * should call #amqp_destroy_envelope() when it is done using + * the fields in the envelope object. The caller is responsible + * for allocating/destroying the amqp_envelope_t object itself. + * \param [in] timeout a timeout to wait for a message delivery. Passing in + * NULL will result in blocking behavior. + * \param [in] flags pass in 0. Currently unused. + * \returns a amqp_rpc_reply_t object. ret.reply_type == AMQP_RESPONSE_NORMAL + * on success. If ret.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION, + * and ret.library_error == AMQP_STATUS_UNEXPECTED_STATE, a frame other + * than AMQP_BASIC_DELIVER_METHOD was received, the caller should call + * amqp_simple_wait_frame() to read this frame and take appropriate + * action. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_rpc_reply_t AMQP_CALL amqp_consume_message(amqp_connection_state_t state, + amqp_envelope_t *envelope, + struct timeval *timeout, + int flags); + +/** + * Frees memory associated with a amqp_envelope_t allocated in + * amqp_consume_message() + * + * \param [in] envelope + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_destroy_envelope(amqp_envelope_t *envelope); + +/** + * Parameters used to connect to the RabbitMQ broker + * + * \since v0.2 + */ +struct amqp_connection_info { + char *user; /**< the username to authenticate with the broker, default on most + broker is 'guest' */ + char *password; /**< the password to authenticate with the broker, default on + most brokers is 'guest' */ + char *host; /**< the hostname of the broker */ + char *vhost; /**< the virtual host on the broker to connect to, a good default + is "/" */ + int port; /**< the port that the broker is listening on, default on most + brokers is 5672 */ + amqp_boolean_t ssl; +}; + +/** + * Initialze an amqp_connection_info to default values + * + * The default values are: + * - user: "guest" + * - password: "guest" + * - host: "localhost" + * - vhost: "/" + * - port: 5672 + * + * \param [out] parsed the connection info to set defaults on + * + * \since v0.2 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL + amqp_default_connection_info(struct amqp_connection_info *parsed); + +/** + * Parse a connection URL + * + * An amqp connection url takes the form: + * + * amqp://[$USERNAME[:$PASSWORD]\@]$HOST[:$PORT]/[$VHOST] + * + * Examples: + * amqp://guest:guest\@localhost:5672// + * amqp://guest:guest\@localhost/myvhost + * + * Any missing parts of the URL will be set to the defaults specified in + * amqp_default_connection_info. For amqps: URLs the default port will be set + * to 5671 instead of 5672 for non-SSL URLs. + * + * \note This function modifies url parameter. + * + * \param [in] url URI to parse, note that this parameter is modified by the + * function. + * \param [out] parsed the connection info gleaned from the URI. The char* + * members will point to parts of the url input parameter. + * Memory management will depend on how the url is allocated. + * \returns AMQP_STATUS_OK on success, AMQP_STATUS_BAD_URL on failure + * + * \since v0.2 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_parse_url(char *url, struct amqp_connection_info *parsed); + +/* socket API */ + +/** + * Open a socket connection. + * + * This function opens a socket connection returned from amqp_tcp_socket_new() + * or amqp_ssl_socket_new(). This function should be called after setting + * socket options and prior to assigning the socket to an AMQP connection with + * amqp_set_socket(). + * + * \param [in,out] self A socket object. + * \param [in] host Connect to this host. + * \param [in] port Connect on this remote port. + * + * \return AMQP_STATUS_OK on success, an amqp_status_enum on failure + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_socket_open(amqp_socket_t *self, const char *host, int port); + +/** + * Open a socket connection. + * + * This function opens a socket connection returned from amqp_tcp_socket_new() + * or amqp_ssl_socket_new(). This function should be called after setting + * socket options and prior to assigning the socket to an AMQP connection with + * amqp_set_socket(). + * + * \param [in,out] self A socket object. + * \param [in] host Connect to this host. + * \param [in] port Connect on this remote port. + * \param [in] timeout Max allowed time to spent on opening. If NULL - run in + * blocking mode + * + * \return AMQP_STATUS_OK on success, an amqp_status_enum on failure. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_socket_open_noblock(amqp_socket_t *self, const char *host, + int port, struct timeval *timeout); + +/** + * Get the socket descriptor in use by a socket object. + * + * Retrieve the underlying socket descriptor. This function can be used to + * perform low-level socket operations that aren't supported by the socket + * interface. Use with caution! + * + * \param [in,out] self A socket object. + * + * \return The underlying socket descriptor, or -1 if there is no socket + * descriptor associated with + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_socket_get_sockfd(amqp_socket_t *self); + +/** + * Get the socket object associated with a amqp_connection_state_t + * + * \param [in] state the connection object to get the socket from + * \return a pointer to the socket object, or NULL if one has not been assigned + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_socket_t *AMQP_CALL amqp_get_socket(amqp_connection_state_t state); + +/** + * Get the broker properties table + * + * \param [in] state the connection object + * \return a pointer to an amqp_table_t containing the properties advertised + * by the broker on connection. The connection object owns the table, it + * should not be modified. + * + * \since v0.5.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_table_t *AMQP_CALL + amqp_get_server_properties(amqp_connection_state_t state); + +/** + * Get the client properties table + * + * Get the properties that were passed to the broker on connection. + * + * \param [in] state the connection object + * \return a pointer to an amqp_table_t containing the properties advertised + * by the client on connection. The connection object owns the table, it + * should not be modified. + * + * \since v0.7.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_table_t *AMQP_CALL + amqp_get_client_properties(amqp_connection_state_t state); + +/** + * Get the login handshake timeout. + * + * amqp_login and amqp_login_with_properties perform the login handshake with + * the broker. This function returns the timeout associated with completing + * this operation from the client side. This value can be set by using the + * amqp_set_handshake_timeout. + * + * Note that the RabbitMQ broker has configurable timeout for completing the + * login handshake, the default is 10 seconds. rabbitmq-c has a default of 12 + * seconds. + * + * \param [in] state the connection object + * \return a struct timeval representing the current login timeout for the state + * object. A NULL value represents an infinite timeout. The memory returned is + * owned by the connection object. + * + * \since v0.9.0 + */ +AMQP_PUBLIC_FUNCTION +struct timeval *AMQP_CALL + amqp_get_handshake_timeout(amqp_connection_state_t state); + +/** + * Set the login handshake timeout. + * + * amqp_login and amqp_login_with_properties perform the login handshake with + * the broker. This function sets the timeout associated with completing this + * operation from the client side. + * + * The timeout must be set before amqp_login or amqp_login_with_properties is + * called to change from the default timeout. + * + * Note that the RabbitMQ broker has a configurable timeout for completing the + * login handshake, the default is 10 seconds. rabbitmq-c has a default of 12 + * seconds. + * + * \param [in] state the connection object + * \param [in] timeout a struct timeval* representing new login timeout for the + * state object. NULL represents an infinite timeout. The value of timeout is + * copied internally, the caller is responsible for ownership of the passed in + * pointer, it does not need to remain valid after this function is called. + * \return AMQP_STATUS_OK on success. + * + * \since v0.9.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_set_handshake_timeout(amqp_connection_state_t state, + struct timeval *timeout); + +/** + * Get the RPC timeout + * + * Gets the timeout for any RPC-style AMQP command (e.g., amqp_queue_declare). + * This timeout may be changed at any time by calling \amqp_set_rpc_timeout + * function with a new timeout. The timeout applies individually to each RPC + * that is made. + * + * The default value is NULL, or an infinite timeout. + * + * When an RPC times out, the function will return an error AMQP_STATUS_TIMEOUT, + * and the connection will be closed. + * + *\warning RPC-timeouts are an advanced feature intended to be used to detect + * dead connections quickly when the rabbitmq-c implementation of heartbeats + * does not work. Do not use RPC timeouts unless you understand the implications + * of doing so. + * + * \param [in] state the connection object + * \return a struct timeval representing the current RPC timeout for the state + * object. A NULL value represents an infinite timeout. The memory returned is + * owned by the connection object. + * + * \since v0.9.0 + */ +AMQP_PUBLIC_FUNCTION +struct timeval *AMQP_CALL amqp_get_rpc_timeout(amqp_connection_state_t state); + +/** + * Set the RPC timeout + * + * Sets the timeout for any RPC-style AMQP command (e.g., amqp_queue_declare). + * This timeout may be changed at any time by calling this function with a new + * timeout. The timeout applies individually to each RPC that is made. + * + * The default value is NULL, or an infinite timeout. + * + * When an RPC times out, the function will return an error AMQP_STATUS_TIMEOUT, + * and the connection will be closed. + * + *\warning RPC-timeouts are an advanced feature intended to be used to detect + * dead connections quickly when the rabbitmq-c implementation of heartbeats + * does not work. Do not use RPC timeouts unless you understand the implications + * of doing so. + * + * \param [in] state the connection object + * \param [in] timeout a struct timeval* representing new RPC timeout for the + * state object. NULL represents an infinite timeout. The value of timeout is + * copied internally, the caller is responsible for ownership of the passed + * pointer, it does not need to remain valid after this function is called. + * \return AMQP_STATUS_SUCCESS on success. + * + * \since v0.9.0 + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_set_rpc_timeout(amqp_connection_state_t state, + struct timeval *timeout); + +AMQP_END_DECLS + +#endif /* AMQP_H */ diff --git a/ext/librabbitmq/centos_x64/include/amqp_framing.h b/ext/librabbitmq/centos_x64/include/amqp_framing.h new file mode 100644 index 000000000..fb20acc1f --- /dev/null +++ b/ext/librabbitmq/centos_x64/include/amqp_framing.h @@ -0,0 +1,1144 @@ +/* Generated code. Do not edit. Edit and re-run codegen.py instead. + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MIT + * + * Portions created by Alan Antonuk are Copyright (c) 2012-2013 + * Alan Antonuk. All Rights Reserved. + * + * Portions created by VMware are Copyright (c) 2007-2012 VMware, Inc. + * All Rights Reserved. + * + * Portions created by Tony Garnock-Jones are Copyright (c) 2009-2010 + * VMware, Inc. and Tony Garnock-Jones. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * ***** END LICENSE BLOCK ***** + */ + +/** @file amqp_framing.h */ +#ifndef AMQP_FRAMING_H +#define AMQP_FRAMING_H + +#include + +AMQP_BEGIN_DECLS + +#define AMQP_PROTOCOL_VERSION_MAJOR 0 /**< AMQP protocol version major */ +#define AMQP_PROTOCOL_VERSION_MINOR 9 /**< AMQP protocol version minor */ +#define AMQP_PROTOCOL_VERSION_REVISION \ + 1 /**< AMQP protocol version revision \ + */ +#define AMQP_PROTOCOL_PORT 5672 /**< Default AMQP Port */ +#define AMQP_FRAME_METHOD 1 /**< Constant: FRAME-METHOD */ +#define AMQP_FRAME_HEADER 2 /**< Constant: FRAME-HEADER */ +#define AMQP_FRAME_BODY 3 /**< Constant: FRAME-BODY */ +#define AMQP_FRAME_HEARTBEAT 8 /**< Constant: FRAME-HEARTBEAT */ +#define AMQP_FRAME_MIN_SIZE 4096 /**< Constant: FRAME-MIN-SIZE */ +#define AMQP_FRAME_END 206 /**< Constant: FRAME-END */ +#define AMQP_REPLY_SUCCESS 200 /**< Constant: REPLY-SUCCESS */ +#define AMQP_CONTENT_TOO_LARGE 311 /**< Constant: CONTENT-TOO-LARGE */ +#define AMQP_NO_ROUTE 312 /**< Constant: NO-ROUTE */ +#define AMQP_NO_CONSUMERS 313 /**< Constant: NO-CONSUMERS */ +#define AMQP_ACCESS_REFUSED 403 /**< Constant: ACCESS-REFUSED */ +#define AMQP_NOT_FOUND 404 /**< Constant: NOT-FOUND */ +#define AMQP_RESOURCE_LOCKED 405 /**< Constant: RESOURCE-LOCKED */ +#define AMQP_PRECONDITION_FAILED 406 /**< Constant: PRECONDITION-FAILED */ +#define AMQP_CONNECTION_FORCED 320 /**< Constant: CONNECTION-FORCED */ +#define AMQP_INVALID_PATH 402 /**< Constant: INVALID-PATH */ +#define AMQP_FRAME_ERROR 501 /**< Constant: FRAME-ERROR */ +#define AMQP_SYNTAX_ERROR 502 /**< Constant: SYNTAX-ERROR */ +#define AMQP_COMMAND_INVALID 503 /**< Constant: COMMAND-INVALID */ +#define AMQP_CHANNEL_ERROR 504 /**< Constant: CHANNEL-ERROR */ +#define AMQP_UNEXPECTED_FRAME 505 /**< Constant: UNEXPECTED-FRAME */ +#define AMQP_RESOURCE_ERROR 506 /**< Constant: RESOURCE-ERROR */ +#define AMQP_NOT_ALLOWED 530 /**< Constant: NOT-ALLOWED */ +#define AMQP_NOT_IMPLEMENTED 540 /**< Constant: NOT-IMPLEMENTED */ +#define AMQP_INTERNAL_ERROR 541 /**< Constant: INTERNAL-ERROR */ + +/* Function prototypes. */ + +/** + * Get constant name string from constant + * + * @param [in] constantNumber constant to get the name of + * @returns string describing the constant. String is managed by + * the library and should not be free()'d by the program + */ +AMQP_PUBLIC_FUNCTION +char const *AMQP_CALL amqp_constant_name(int constantNumber); + +/** + * Checks to see if a constant is a hard error + * + * A hard error occurs when something severe enough + * happens that the connection must be closed. + * + * @param [in] constantNumber the error constant + * @returns true if its a hard error, false otherwise + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t AMQP_CALL amqp_constant_is_hard_error(int constantNumber); + +/** + * Get method name string from method number + * + * @param [in] methodNumber the method number + * @returns method name string. String is managed by the library + * and should not be freed()'d by the program + */ +AMQP_PUBLIC_FUNCTION +char const *AMQP_CALL amqp_method_name(amqp_method_number_t methodNumber); + +/** + * Check whether a method has content + * + * A method that has content will receive the method frame + * a properties frame, then 1 to N body frames + * + * @param [in] methodNumber the method number + * @returns true if method has content, false otherwise + */ +AMQP_PUBLIC_FUNCTION +amqp_boolean_t AMQP_CALL + amqp_method_has_content(amqp_method_number_t methodNumber); + +/** + * Decodes a method from AMQP wireformat + * + * @param [in] methodNumber the method number for the decoded parameter + * @param [in] pool the memory pool to allocate the decoded method from + * @param [in] encoded the encoded byte string buffer + * @param [out] decoded pointer to the decoded method struct + * @returns 0 on success, an error code otherwise + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_decode_method(amqp_method_number_t methodNumber, + amqp_pool_t *pool, amqp_bytes_t encoded, + void **decoded); + +/** + * Decodes a header frame properties structure from AMQP wireformat + * + * @param [in] class_id the class id for the decoded parameter + * @param [in] pool the memory pool to allocate the decoded properties from + * @param [in] encoded the encoded byte string buffer + * @param [out] decoded pointer to the decoded properties struct + * @returns 0 on success, an error code otherwise + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_decode_properties(uint16_t class_id, amqp_pool_t *pool, + amqp_bytes_t encoded, void **decoded); + +/** + * Encodes a method structure in AMQP wireformat + * + * @param [in] methodNumber the method number for the decoded parameter + * @param [in] decoded the method structure (e.g., amqp_connection_start_t) + * @param [in] encoded an allocated byte buffer for the encoded method + * structure to be written to. If the buffer isn't large enough + * to hold the encoded method, an error code will be returned. + * @returns 0 on success, an error code otherwise. + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_encode_method(amqp_method_number_t methodNumber, + void *decoded, amqp_bytes_t encoded); + +/** + * Encodes a properties structure in AMQP wireformat + * + * @param [in] class_id the class id for the decoded parameter + * @param [in] decoded the properties structure (e.g., amqp_basic_properties_t) + * @param [in] encoded an allocated byte buffer for the encoded properties to + * written to. + * If the buffer isn't large enough to hold the encoded method, an + * an error code will be returned + * @returns 0 on success, an error code otherwise. + */ +AMQP_PUBLIC_FUNCTION +int AMQP_CALL amqp_encode_properties(uint16_t class_id, void *decoded, + amqp_bytes_t encoded); + +/* Method field records. */ + +#define AMQP_CONNECTION_START_METHOD \ + ((amqp_method_number_t)0x000A000A) /**< connection.start method id \ + @internal 10, 10; 655370 */ +/** connection.start method fields */ +typedef struct amqp_connection_start_t_ { + uint8_t version_major; /**< version-major */ + uint8_t version_minor; /**< version-minor */ + amqp_table_t server_properties; /**< server-properties */ + amqp_bytes_t mechanisms; /**< mechanisms */ + amqp_bytes_t locales; /**< locales */ +} amqp_connection_start_t; + +#define AMQP_CONNECTION_START_OK_METHOD \ + ((amqp_method_number_t)0x000A000B) /**< connection.start-ok method id \ + @internal 10, 11; 655371 */ +/** connection.start-ok method fields */ +typedef struct amqp_connection_start_ok_t_ { + amqp_table_t client_properties; /**< client-properties */ + amqp_bytes_t mechanism; /**< mechanism */ + amqp_bytes_t response; /**< response */ + amqp_bytes_t locale; /**< locale */ +} amqp_connection_start_ok_t; + +#define AMQP_CONNECTION_SECURE_METHOD \ + ((amqp_method_number_t)0x000A0014) /**< connection.secure method id \ + @internal 10, 20; 655380 */ +/** connection.secure method fields */ +typedef struct amqp_connection_secure_t_ { + amqp_bytes_t challenge; /**< challenge */ +} amqp_connection_secure_t; + +#define AMQP_CONNECTION_SECURE_OK_METHOD \ + ((amqp_method_number_t)0x000A0015) /**< connection.secure-ok method id \ + @internal 10, 21; 655381 */ +/** connection.secure-ok method fields */ +typedef struct amqp_connection_secure_ok_t_ { + amqp_bytes_t response; /**< response */ +} amqp_connection_secure_ok_t; + +#define AMQP_CONNECTION_TUNE_METHOD \ + ((amqp_method_number_t)0x000A001E) /**< connection.tune method id \ + @internal 10, 30; 655390 */ +/** connection.tune method fields */ +typedef struct amqp_connection_tune_t_ { + uint16_t channel_max; /**< channel-max */ + uint32_t frame_max; /**< frame-max */ + uint16_t heartbeat; /**< heartbeat */ +} amqp_connection_tune_t; + +#define AMQP_CONNECTION_TUNE_OK_METHOD \ + ((amqp_method_number_t)0x000A001F) /**< connection.tune-ok method id \ + @internal 10, 31; 655391 */ +/** connection.tune-ok method fields */ +typedef struct amqp_connection_tune_ok_t_ { + uint16_t channel_max; /**< channel-max */ + uint32_t frame_max; /**< frame-max */ + uint16_t heartbeat; /**< heartbeat */ +} amqp_connection_tune_ok_t; + +#define AMQP_CONNECTION_OPEN_METHOD \ + ((amqp_method_number_t)0x000A0028) /**< connection.open method id \ + @internal 10, 40; 655400 */ +/** connection.open method fields */ +typedef struct amqp_connection_open_t_ { + amqp_bytes_t virtual_host; /**< virtual-host */ + amqp_bytes_t capabilities; /**< capabilities */ + amqp_boolean_t insist; /**< insist */ +} amqp_connection_open_t; + +#define AMQP_CONNECTION_OPEN_OK_METHOD \ + ((amqp_method_number_t)0x000A0029) /**< connection.open-ok method id \ + @internal 10, 41; 655401 */ +/** connection.open-ok method fields */ +typedef struct amqp_connection_open_ok_t_ { + amqp_bytes_t known_hosts; /**< known-hosts */ +} amqp_connection_open_ok_t; + +#define AMQP_CONNECTION_CLOSE_METHOD \ + ((amqp_method_number_t)0x000A0032) /**< connection.close method id \ + @internal 10, 50; 655410 */ +/** connection.close method fields */ +typedef struct amqp_connection_close_t_ { + uint16_t reply_code; /**< reply-code */ + amqp_bytes_t reply_text; /**< reply-text */ + uint16_t class_id; /**< class-id */ + uint16_t method_id; /**< method-id */ +} amqp_connection_close_t; + +#define AMQP_CONNECTION_CLOSE_OK_METHOD \ + ((amqp_method_number_t)0x000A0033) /**< connection.close-ok method id \ + @internal 10, 51; 655411 */ +/** connection.close-ok method fields */ +typedef struct amqp_connection_close_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_connection_close_ok_t; + +#define AMQP_CONNECTION_BLOCKED_METHOD \ + ((amqp_method_number_t)0x000A003C) /**< connection.blocked method id \ + @internal 10, 60; 655420 */ +/** connection.blocked method fields */ +typedef struct amqp_connection_blocked_t_ { + amqp_bytes_t reason; /**< reason */ +} amqp_connection_blocked_t; + +#define AMQP_CONNECTION_UNBLOCKED_METHOD \ + ((amqp_method_number_t)0x000A003D) /**< connection.unblocked method id \ + @internal 10, 61; 655421 */ +/** connection.unblocked method fields */ +typedef struct amqp_connection_unblocked_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_connection_unblocked_t; + +#define AMQP_CHANNEL_OPEN_METHOD \ + ((amqp_method_number_t)0x0014000A) /**< channel.open method id @internal \ + 20, 10; 1310730 */ +/** channel.open method fields */ +typedef struct amqp_channel_open_t_ { + amqp_bytes_t out_of_band; /**< out-of-band */ +} amqp_channel_open_t; + +#define AMQP_CHANNEL_OPEN_OK_METHOD \ + ((amqp_method_number_t)0x0014000B) /**< channel.open-ok method id \ + @internal 20, 11; 1310731 */ +/** channel.open-ok method fields */ +typedef struct amqp_channel_open_ok_t_ { + amqp_bytes_t channel_id; /**< channel-id */ +} amqp_channel_open_ok_t; + +#define AMQP_CHANNEL_FLOW_METHOD \ + ((amqp_method_number_t)0x00140014) /**< channel.flow method id @internal \ + 20, 20; 1310740 */ +/** channel.flow method fields */ +typedef struct amqp_channel_flow_t_ { + amqp_boolean_t active; /**< active */ +} amqp_channel_flow_t; + +#define AMQP_CHANNEL_FLOW_OK_METHOD \ + ((amqp_method_number_t)0x00140015) /**< channel.flow-ok method id \ + @internal 20, 21; 1310741 */ +/** channel.flow-ok method fields */ +typedef struct amqp_channel_flow_ok_t_ { + amqp_boolean_t active; /**< active */ +} amqp_channel_flow_ok_t; + +#define AMQP_CHANNEL_CLOSE_METHOD \ + ((amqp_method_number_t)0x00140028) /**< channel.close method id @internal \ + 20, 40; 1310760 */ +/** channel.close method fields */ +typedef struct amqp_channel_close_t_ { + uint16_t reply_code; /**< reply-code */ + amqp_bytes_t reply_text; /**< reply-text */ + uint16_t class_id; /**< class-id */ + uint16_t method_id; /**< method-id */ +} amqp_channel_close_t; + +#define AMQP_CHANNEL_CLOSE_OK_METHOD \ + ((amqp_method_number_t)0x00140029) /**< channel.close-ok method id \ + @internal 20, 41; 1310761 */ +/** channel.close-ok method fields */ +typedef struct amqp_channel_close_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_channel_close_ok_t; + +#define AMQP_ACCESS_REQUEST_METHOD \ + ((amqp_method_number_t)0x001E000A) /**< access.request method id @internal \ + 30, 10; 1966090 */ +/** access.request method fields */ +typedef struct amqp_access_request_t_ { + amqp_bytes_t realm; /**< realm */ + amqp_boolean_t exclusive; /**< exclusive */ + amqp_boolean_t passive; /**< passive */ + amqp_boolean_t active; /**< active */ + amqp_boolean_t write; /**< write */ + amqp_boolean_t read; /**< read */ +} amqp_access_request_t; + +#define AMQP_ACCESS_REQUEST_OK_METHOD \ + ((amqp_method_number_t)0x001E000B) /**< access.request-ok method id \ + @internal 30, 11; 1966091 */ +/** access.request-ok method fields */ +typedef struct amqp_access_request_ok_t_ { + uint16_t ticket; /**< ticket */ +} amqp_access_request_ok_t; + +#define AMQP_EXCHANGE_DECLARE_METHOD \ + ((amqp_method_number_t)0x0028000A) /**< exchange.declare method id \ + @internal 40, 10; 2621450 */ +/** exchange.declare method fields */ +typedef struct amqp_exchange_declare_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t type; /**< type */ + amqp_boolean_t passive; /**< passive */ + amqp_boolean_t durable; /**< durable */ + amqp_boolean_t auto_delete; /**< auto-delete */ + amqp_boolean_t internal; /**< internal */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_exchange_declare_t; + +#define AMQP_EXCHANGE_DECLARE_OK_METHOD \ + ((amqp_method_number_t)0x0028000B) /**< exchange.declare-ok method id \ + @internal 40, 11; 2621451 */ +/** exchange.declare-ok method fields */ +typedef struct amqp_exchange_declare_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_exchange_declare_ok_t; + +#define AMQP_EXCHANGE_DELETE_METHOD \ + ((amqp_method_number_t)0x00280014) /**< exchange.delete method id \ + @internal 40, 20; 2621460 */ +/** exchange.delete method fields */ +typedef struct amqp_exchange_delete_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t exchange; /**< exchange */ + amqp_boolean_t if_unused; /**< if-unused */ + amqp_boolean_t nowait; /**< nowait */ +} amqp_exchange_delete_t; + +#define AMQP_EXCHANGE_DELETE_OK_METHOD \ + ((amqp_method_number_t)0x00280015) /**< exchange.delete-ok method id \ + @internal 40, 21; 2621461 */ +/** exchange.delete-ok method fields */ +typedef struct amqp_exchange_delete_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_exchange_delete_ok_t; + +#define AMQP_EXCHANGE_BIND_METHOD \ + ((amqp_method_number_t)0x0028001E) /**< exchange.bind method id @internal \ + 40, 30; 2621470 */ +/** exchange.bind method fields */ +typedef struct amqp_exchange_bind_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t destination; /**< destination */ + amqp_bytes_t source; /**< source */ + amqp_bytes_t routing_key; /**< routing-key */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_exchange_bind_t; + +#define AMQP_EXCHANGE_BIND_OK_METHOD \ + ((amqp_method_number_t)0x0028001F) /**< exchange.bind-ok method id \ + @internal 40, 31; 2621471 */ +/** exchange.bind-ok method fields */ +typedef struct amqp_exchange_bind_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_exchange_bind_ok_t; + +#define AMQP_EXCHANGE_UNBIND_METHOD \ + ((amqp_method_number_t)0x00280028) /**< exchange.unbind method id \ + @internal 40, 40; 2621480 */ +/** exchange.unbind method fields */ +typedef struct amqp_exchange_unbind_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t destination; /**< destination */ + amqp_bytes_t source; /**< source */ + amqp_bytes_t routing_key; /**< routing-key */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_exchange_unbind_t; + +#define AMQP_EXCHANGE_UNBIND_OK_METHOD \ + ((amqp_method_number_t)0x00280033) /**< exchange.unbind-ok method id \ + @internal 40, 51; 2621491 */ +/** exchange.unbind-ok method fields */ +typedef struct amqp_exchange_unbind_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_exchange_unbind_ok_t; + +#define AMQP_QUEUE_DECLARE_METHOD \ + ((amqp_method_number_t)0x0032000A) /**< queue.declare method id @internal \ + 50, 10; 3276810 */ +/** queue.declare method fields */ +typedef struct amqp_queue_declare_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_boolean_t passive; /**< passive */ + amqp_boolean_t durable; /**< durable */ + amqp_boolean_t exclusive; /**< exclusive */ + amqp_boolean_t auto_delete; /**< auto-delete */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_queue_declare_t; + +#define AMQP_QUEUE_DECLARE_OK_METHOD \ + ((amqp_method_number_t)0x0032000B) /**< queue.declare-ok method id \ + @internal 50, 11; 3276811 */ +/** queue.declare-ok method fields */ +typedef struct amqp_queue_declare_ok_t_ { + amqp_bytes_t queue; /**< queue */ + uint32_t message_count; /**< message-count */ + uint32_t consumer_count; /**< consumer-count */ +} amqp_queue_declare_ok_t; + +#define AMQP_QUEUE_BIND_METHOD \ + ((amqp_method_number_t)0x00320014) /**< queue.bind method id @internal 50, \ + 20; 3276820 */ +/** queue.bind method fields */ +typedef struct amqp_queue_bind_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_queue_bind_t; + +#define AMQP_QUEUE_BIND_OK_METHOD \ + ((amqp_method_number_t)0x00320015) /**< queue.bind-ok method id @internal \ + 50, 21; 3276821 */ +/** queue.bind-ok method fields */ +typedef struct amqp_queue_bind_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_queue_bind_ok_t; + +#define AMQP_QUEUE_PURGE_METHOD \ + ((amqp_method_number_t)0x0032001E) /**< queue.purge method id @internal \ + 50, 30; 3276830 */ +/** queue.purge method fields */ +typedef struct amqp_queue_purge_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_boolean_t nowait; /**< nowait */ +} amqp_queue_purge_t; + +#define AMQP_QUEUE_PURGE_OK_METHOD \ + ((amqp_method_number_t)0x0032001F) /**< queue.purge-ok method id @internal \ + 50, 31; 3276831 */ +/** queue.purge-ok method fields */ +typedef struct amqp_queue_purge_ok_t_ { + uint32_t message_count; /**< message-count */ +} amqp_queue_purge_ok_t; + +#define AMQP_QUEUE_DELETE_METHOD \ + ((amqp_method_number_t)0x00320028) /**< queue.delete method id @internal \ + 50, 40; 3276840 */ +/** queue.delete method fields */ +typedef struct amqp_queue_delete_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_boolean_t if_unused; /**< if-unused */ + amqp_boolean_t if_empty; /**< if-empty */ + amqp_boolean_t nowait; /**< nowait */ +} amqp_queue_delete_t; + +#define AMQP_QUEUE_DELETE_OK_METHOD \ + ((amqp_method_number_t)0x00320029) /**< queue.delete-ok method id \ + @internal 50, 41; 3276841 */ +/** queue.delete-ok method fields */ +typedef struct amqp_queue_delete_ok_t_ { + uint32_t message_count; /**< message-count */ +} amqp_queue_delete_ok_t; + +#define AMQP_QUEUE_UNBIND_METHOD \ + ((amqp_method_number_t)0x00320032) /**< queue.unbind method id @internal \ + 50, 50; 3276850 */ +/** queue.unbind method fields */ +typedef struct amqp_queue_unbind_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ + amqp_table_t arguments; /**< arguments */ +} amqp_queue_unbind_t; + +#define AMQP_QUEUE_UNBIND_OK_METHOD \ + ((amqp_method_number_t)0x00320033) /**< queue.unbind-ok method id \ + @internal 50, 51; 3276851 */ +/** queue.unbind-ok method fields */ +typedef struct amqp_queue_unbind_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_queue_unbind_ok_t; + +#define AMQP_BASIC_QOS_METHOD \ + ((amqp_method_number_t)0x003C000A) /**< basic.qos method id @internal 60, \ + 10; 3932170 */ +/** basic.qos method fields */ +typedef struct amqp_basic_qos_t_ { + uint32_t prefetch_size; /**< prefetch-size */ + uint16_t prefetch_count; /**< prefetch-count */ + amqp_boolean_t global; /**< global */ +} amqp_basic_qos_t; + +#define AMQP_BASIC_QOS_OK_METHOD \ + ((amqp_method_number_t)0x003C000B) /**< basic.qos-ok method id @internal \ + 60, 11; 3932171 */ +/** basic.qos-ok method fields */ +typedef struct amqp_basic_qos_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_basic_qos_ok_t; + +#define AMQP_BASIC_CONSUME_METHOD \ + ((amqp_method_number_t)0x003C0014) /**< basic.consume method id @internal \ + 60, 20; 3932180 */ +/** basic.consume method fields */ +typedef struct amqp_basic_consume_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_bytes_t consumer_tag; /**< consumer-tag */ + amqp_boolean_t no_local; /**< no-local */ + amqp_boolean_t no_ack; /**< no-ack */ + amqp_boolean_t exclusive; /**< exclusive */ + amqp_boolean_t nowait; /**< nowait */ + amqp_table_t arguments; /**< arguments */ +} amqp_basic_consume_t; + +#define AMQP_BASIC_CONSUME_OK_METHOD \ + ((amqp_method_number_t)0x003C0015) /**< basic.consume-ok method id \ + @internal 60, 21; 3932181 */ +/** basic.consume-ok method fields */ +typedef struct amqp_basic_consume_ok_t_ { + amqp_bytes_t consumer_tag; /**< consumer-tag */ +} amqp_basic_consume_ok_t; + +#define AMQP_BASIC_CANCEL_METHOD \ + ((amqp_method_number_t)0x003C001E) /**< basic.cancel method id @internal \ + 60, 30; 3932190 */ +/** basic.cancel method fields */ +typedef struct amqp_basic_cancel_t_ { + amqp_bytes_t consumer_tag; /**< consumer-tag */ + amqp_boolean_t nowait; /**< nowait */ +} amqp_basic_cancel_t; + +#define AMQP_BASIC_CANCEL_OK_METHOD \ + ((amqp_method_number_t)0x003C001F) /**< basic.cancel-ok method id \ + @internal 60, 31; 3932191 */ +/** basic.cancel-ok method fields */ +typedef struct amqp_basic_cancel_ok_t_ { + amqp_bytes_t consumer_tag; /**< consumer-tag */ +} amqp_basic_cancel_ok_t; + +#define AMQP_BASIC_PUBLISH_METHOD \ + ((amqp_method_number_t)0x003C0028) /**< basic.publish method id @internal \ + 60, 40; 3932200 */ +/** basic.publish method fields */ +typedef struct amqp_basic_publish_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ + amqp_boolean_t mandatory; /**< mandatory */ + amqp_boolean_t immediate; /**< immediate */ +} amqp_basic_publish_t; + +#define AMQP_BASIC_RETURN_METHOD \ + ((amqp_method_number_t)0x003C0032) /**< basic.return method id @internal \ + 60, 50; 3932210 */ +/** basic.return method fields */ +typedef struct amqp_basic_return_t_ { + uint16_t reply_code; /**< reply-code */ + amqp_bytes_t reply_text; /**< reply-text */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ +} amqp_basic_return_t; + +#define AMQP_BASIC_DELIVER_METHOD \ + ((amqp_method_number_t)0x003C003C) /**< basic.deliver method id @internal \ + 60, 60; 3932220 */ +/** basic.deliver method fields */ +typedef struct amqp_basic_deliver_t_ { + amqp_bytes_t consumer_tag; /**< consumer-tag */ + uint64_t delivery_tag; /**< delivery-tag */ + amqp_boolean_t redelivered; /**< redelivered */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ +} amqp_basic_deliver_t; + +#define AMQP_BASIC_GET_METHOD \ + ((amqp_method_number_t)0x003C0046) /**< basic.get method id @internal 60, \ + 70; 3932230 */ +/** basic.get method fields */ +typedef struct amqp_basic_get_t_ { + uint16_t ticket; /**< ticket */ + amqp_bytes_t queue; /**< queue */ + amqp_boolean_t no_ack; /**< no-ack */ +} amqp_basic_get_t; + +#define AMQP_BASIC_GET_OK_METHOD \ + ((amqp_method_number_t)0x003C0047) /**< basic.get-ok method id @internal \ + 60, 71; 3932231 */ +/** basic.get-ok method fields */ +typedef struct amqp_basic_get_ok_t_ { + uint64_t delivery_tag; /**< delivery-tag */ + amqp_boolean_t redelivered; /**< redelivered */ + amqp_bytes_t exchange; /**< exchange */ + amqp_bytes_t routing_key; /**< routing-key */ + uint32_t message_count; /**< message-count */ +} amqp_basic_get_ok_t; + +#define AMQP_BASIC_GET_EMPTY_METHOD \ + ((amqp_method_number_t)0x003C0048) /**< basic.get-empty method id \ + @internal 60, 72; 3932232 */ +/** basic.get-empty method fields */ +typedef struct amqp_basic_get_empty_t_ { + amqp_bytes_t cluster_id; /**< cluster-id */ +} amqp_basic_get_empty_t; + +#define AMQP_BASIC_ACK_METHOD \ + ((amqp_method_number_t)0x003C0050) /**< basic.ack method id @internal 60, \ + 80; 3932240 */ +/** basic.ack method fields */ +typedef struct amqp_basic_ack_t_ { + uint64_t delivery_tag; /**< delivery-tag */ + amqp_boolean_t multiple; /**< multiple */ +} amqp_basic_ack_t; + +#define AMQP_BASIC_REJECT_METHOD \ + ((amqp_method_number_t)0x003C005A) /**< basic.reject method id @internal \ + 60, 90; 3932250 */ +/** basic.reject method fields */ +typedef struct amqp_basic_reject_t_ { + uint64_t delivery_tag; /**< delivery-tag */ + amqp_boolean_t requeue; /**< requeue */ +} amqp_basic_reject_t; + +#define AMQP_BASIC_RECOVER_ASYNC_METHOD \ + ((amqp_method_number_t)0x003C0064) /**< basic.recover-async method id \ + @internal 60, 100; 3932260 */ +/** basic.recover-async method fields */ +typedef struct amqp_basic_recover_async_t_ { + amqp_boolean_t requeue; /**< requeue */ +} amqp_basic_recover_async_t; + +#define AMQP_BASIC_RECOVER_METHOD \ + ((amqp_method_number_t)0x003C006E) /**< basic.recover method id @internal \ + 60, 110; 3932270 */ +/** basic.recover method fields */ +typedef struct amqp_basic_recover_t_ { + amqp_boolean_t requeue; /**< requeue */ +} amqp_basic_recover_t; + +#define AMQP_BASIC_RECOVER_OK_METHOD \ + ((amqp_method_number_t)0x003C006F) /**< basic.recover-ok method id \ + @internal 60, 111; 3932271 */ +/** basic.recover-ok method fields */ +typedef struct amqp_basic_recover_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_basic_recover_ok_t; + +#define AMQP_BASIC_NACK_METHOD \ + ((amqp_method_number_t)0x003C0078) /**< basic.nack method id @internal 60, \ + 120; 3932280 */ +/** basic.nack method fields */ +typedef struct amqp_basic_nack_t_ { + uint64_t delivery_tag; /**< delivery-tag */ + amqp_boolean_t multiple; /**< multiple */ + amqp_boolean_t requeue; /**< requeue */ +} amqp_basic_nack_t; + +#define AMQP_TX_SELECT_METHOD \ + ((amqp_method_number_t)0x005A000A) /**< tx.select method id @internal 90, \ + 10; 5898250 */ +/** tx.select method fields */ +typedef struct amqp_tx_select_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_select_t; + +#define AMQP_TX_SELECT_OK_METHOD \ + ((amqp_method_number_t)0x005A000B) /**< tx.select-ok method id @internal \ + 90, 11; 5898251 */ +/** tx.select-ok method fields */ +typedef struct amqp_tx_select_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_select_ok_t; + +#define AMQP_TX_COMMIT_METHOD \ + ((amqp_method_number_t)0x005A0014) /**< tx.commit method id @internal 90, \ + 20; 5898260 */ +/** tx.commit method fields */ +typedef struct amqp_tx_commit_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_commit_t; + +#define AMQP_TX_COMMIT_OK_METHOD \ + ((amqp_method_number_t)0x005A0015) /**< tx.commit-ok method id @internal \ + 90, 21; 5898261 */ +/** tx.commit-ok method fields */ +typedef struct amqp_tx_commit_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_commit_ok_t; + +#define AMQP_TX_ROLLBACK_METHOD \ + ((amqp_method_number_t)0x005A001E) /**< tx.rollback method id @internal \ + 90, 30; 5898270 */ +/** tx.rollback method fields */ +typedef struct amqp_tx_rollback_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_rollback_t; + +#define AMQP_TX_ROLLBACK_OK_METHOD \ + ((amqp_method_number_t)0x005A001F) /**< tx.rollback-ok method id @internal \ + 90, 31; 5898271 */ +/** tx.rollback-ok method fields */ +typedef struct amqp_tx_rollback_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_rollback_ok_t; + +#define AMQP_CONFIRM_SELECT_METHOD \ + ((amqp_method_number_t)0x0055000A) /**< confirm.select method id @internal \ + 85, 10; 5570570 */ +/** confirm.select method fields */ +typedef struct amqp_confirm_select_t_ { + amqp_boolean_t nowait; /**< nowait */ +} amqp_confirm_select_t; + +#define AMQP_CONFIRM_SELECT_OK_METHOD \ + ((amqp_method_number_t)0x0055000B) /**< confirm.select-ok method id \ + @internal 85, 11; 5570571 */ +/** confirm.select-ok method fields */ +typedef struct amqp_confirm_select_ok_t_ { + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_confirm_select_ok_t; + +/* Class property records. */ +#define AMQP_CONNECTION_CLASS \ + (0x000A) /**< connection class id @internal 10 \ + */ +/** connection class properties */ +typedef struct amqp_connection_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_connection_properties_t; + +#define AMQP_CHANNEL_CLASS (0x0014) /**< channel class id @internal 20 */ +/** channel class properties */ +typedef struct amqp_channel_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_channel_properties_t; + +#define AMQP_ACCESS_CLASS (0x001E) /**< access class id @internal 30 */ +/** access class properties */ +typedef struct amqp_access_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_access_properties_t; + +#define AMQP_EXCHANGE_CLASS (0x0028) /**< exchange class id @internal 40 */ +/** exchange class properties */ +typedef struct amqp_exchange_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_exchange_properties_t; + +#define AMQP_QUEUE_CLASS (0x0032) /**< queue class id @internal 50 */ +/** queue class properties */ +typedef struct amqp_queue_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_queue_properties_t; + +#define AMQP_BASIC_CLASS (0x003C) /**< basic class id @internal 60 */ +#define AMQP_BASIC_CONTENT_TYPE_FLAG (1 << 15) +#define AMQP_BASIC_CONTENT_ENCODING_FLAG (1 << 14) +#define AMQP_BASIC_HEADERS_FLAG (1 << 13) +#define AMQP_BASIC_DELIVERY_MODE_FLAG (1 << 12) +#define AMQP_BASIC_PRIORITY_FLAG (1 << 11) +#define AMQP_BASIC_CORRELATION_ID_FLAG (1 << 10) +#define AMQP_BASIC_REPLY_TO_FLAG (1 << 9) +#define AMQP_BASIC_EXPIRATION_FLAG (1 << 8) +#define AMQP_BASIC_MESSAGE_ID_FLAG (1 << 7) +#define AMQP_BASIC_TIMESTAMP_FLAG (1 << 6) +#define AMQP_BASIC_TYPE_FLAG (1 << 5) +#define AMQP_BASIC_USER_ID_FLAG (1 << 4) +#define AMQP_BASIC_APP_ID_FLAG (1 << 3) +#define AMQP_BASIC_CLUSTER_ID_FLAG (1 << 2) +/** basic class properties */ +typedef struct amqp_basic_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + amqp_bytes_t content_type; /**< content-type */ + amqp_bytes_t content_encoding; /**< content-encoding */ + amqp_table_t headers; /**< headers */ + uint8_t delivery_mode; /**< delivery-mode */ + uint8_t priority; /**< priority */ + amqp_bytes_t correlation_id; /**< correlation-id */ + amqp_bytes_t reply_to; /**< reply-to */ + amqp_bytes_t expiration; /**< expiration */ + amqp_bytes_t message_id; /**< message-id */ + uint64_t timestamp; /**< timestamp */ + amqp_bytes_t type; /**< type */ + amqp_bytes_t user_id; /**< user-id */ + amqp_bytes_t app_id; /**< app-id */ + amqp_bytes_t cluster_id; /**< cluster-id */ +} amqp_basic_properties_t; + +#define AMQP_TX_CLASS (0x005A) /**< tx class id @internal 90 */ +/** tx class properties */ +typedef struct amqp_tx_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_tx_properties_t; + +#define AMQP_CONFIRM_CLASS (0x0055) /**< confirm class id @internal 85 */ +/** confirm class properties */ +typedef struct amqp_confirm_properties_t_ { + amqp_flags_t _flags; /**< bit-mask of set fields */ + char dummy; /**< Dummy field to avoid empty struct */ +} amqp_confirm_properties_t; + +/* API functions for methods */ + +/** + * amqp_channel_open + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_channel_open_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_channel_open_ok_t *AMQP_CALL + amqp_channel_open(amqp_connection_state_t state, amqp_channel_t channel); +/** + * amqp_channel_flow + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] active active + * @returns amqp_channel_flow_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_channel_flow_ok_t *AMQP_CALL + amqp_channel_flow(amqp_connection_state_t state, amqp_channel_t channel, + amqp_boolean_t active); +/** + * amqp_exchange_declare + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] exchange exchange + * @param [in] type type + * @param [in] passive passive + * @param [in] durable durable + * @param [in] auto_delete auto_delete + * @param [in] internal internal + * @param [in] arguments arguments + * @returns amqp_exchange_declare_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_declare_ok_t *AMQP_CALL amqp_exchange_declare( + amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t exchange, amqp_bytes_t type, amqp_boolean_t passive, + amqp_boolean_t durable, amqp_boolean_t auto_delete, amqp_boolean_t internal, + amqp_table_t arguments); +/** + * amqp_exchange_delete + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] exchange exchange + * @param [in] if_unused if_unused + * @returns amqp_exchange_delete_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_delete_ok_t *AMQP_CALL + amqp_exchange_delete(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t exchange, amqp_boolean_t if_unused); +/** + * amqp_exchange_bind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] destination destination + * @param [in] source source + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_exchange_bind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_bind_ok_t *AMQP_CALL + amqp_exchange_bind(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t destination, amqp_bytes_t source, + amqp_bytes_t routing_key, amqp_table_t arguments); +/** + * amqp_exchange_unbind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] destination destination + * @param [in] source source + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_exchange_unbind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_exchange_unbind_ok_t *AMQP_CALL + amqp_exchange_unbind(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t destination, amqp_bytes_t source, + amqp_bytes_t routing_key, amqp_table_t arguments); +/** + * amqp_queue_declare + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] passive passive + * @param [in] durable durable + * @param [in] exclusive exclusive + * @param [in] auto_delete auto_delete + * @param [in] arguments arguments + * @returns amqp_queue_declare_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_declare_ok_t *AMQP_CALL amqp_queue_declare( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_boolean_t passive, amqp_boolean_t durable, amqp_boolean_t exclusive, + amqp_boolean_t auto_delete, amqp_table_t arguments); +/** + * amqp_queue_bind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] exchange exchange + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_queue_bind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_bind_ok_t *AMQP_CALL amqp_queue_bind( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments); +/** + * amqp_queue_purge + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @returns amqp_queue_purge_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_purge_ok_t *AMQP_CALL amqp_queue_purge(amqp_connection_state_t state, + amqp_channel_t channel, + amqp_bytes_t queue); +/** + * amqp_queue_delete + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] if_unused if_unused + * @param [in] if_empty if_empty + * @returns amqp_queue_delete_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_delete_ok_t *AMQP_CALL amqp_queue_delete( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_boolean_t if_unused, amqp_boolean_t if_empty); +/** + * amqp_queue_unbind + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] exchange exchange + * @param [in] routing_key routing_key + * @param [in] arguments arguments + * @returns amqp_queue_unbind_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_queue_unbind_ok_t *AMQP_CALL amqp_queue_unbind( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments); +/** + * amqp_basic_qos + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] prefetch_size prefetch_size + * @param [in] prefetch_count prefetch_count + * @param [in] global global + * @returns amqp_basic_qos_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_qos_ok_t *AMQP_CALL amqp_basic_qos(amqp_connection_state_t state, + amqp_channel_t channel, + uint32_t prefetch_size, + uint16_t prefetch_count, + amqp_boolean_t global); +/** + * amqp_basic_consume + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] queue queue + * @param [in] consumer_tag consumer_tag + * @param [in] no_local no_local + * @param [in] no_ack no_ack + * @param [in] exclusive exclusive + * @param [in] arguments arguments + * @returns amqp_basic_consume_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_consume_ok_t *AMQP_CALL amqp_basic_consume( + amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, + amqp_bytes_t consumer_tag, amqp_boolean_t no_local, amqp_boolean_t no_ack, + amqp_boolean_t exclusive, amqp_table_t arguments); +/** + * amqp_basic_cancel + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] consumer_tag consumer_tag + * @returns amqp_basic_cancel_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_cancel_ok_t *AMQP_CALL + amqp_basic_cancel(amqp_connection_state_t state, amqp_channel_t channel, + amqp_bytes_t consumer_tag); +/** + * amqp_basic_recover + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @param [in] requeue requeue + * @returns amqp_basic_recover_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_basic_recover_ok_t *AMQP_CALL + amqp_basic_recover(amqp_connection_state_t state, amqp_channel_t channel, + amqp_boolean_t requeue); +/** + * amqp_tx_select + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_tx_select_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_tx_select_ok_t *AMQP_CALL amqp_tx_select(amqp_connection_state_t state, + amqp_channel_t channel); +/** + * amqp_tx_commit + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_tx_commit_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_tx_commit_ok_t *AMQP_CALL amqp_tx_commit(amqp_connection_state_t state, + amqp_channel_t channel); +/** + * amqp_tx_rollback + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_tx_rollback_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_tx_rollback_ok_t *AMQP_CALL amqp_tx_rollback(amqp_connection_state_t state, + amqp_channel_t channel); +/** + * amqp_confirm_select + * + * @param [in] state connection state + * @param [in] channel the channel to do the RPC on + * @returns amqp_confirm_select_ok_t + */ +AMQP_PUBLIC_FUNCTION +amqp_confirm_select_ok_t *AMQP_CALL + amqp_confirm_select(amqp_connection_state_t state, amqp_channel_t channel); + +AMQP_END_DECLS + +#endif /* AMQP_FRAMING_H */ diff --git a/ext/librabbitmq/centos_x64/include/amqp_tcp_socket.h b/ext/librabbitmq/centos_x64/include/amqp_tcp_socket.h new file mode 100644 index 000000000..3e9d82f54 --- /dev/null +++ b/ext/librabbitmq/centos_x64/include/amqp_tcp_socket.h @@ -0,0 +1,68 @@ +/** \file */ +/* + * Portions created by Alan Antonuk are Copyright (c) 2013-2014 Alan Antonuk. + * All Rights Reserved. + * + * Portions created by Michael Steinert are Copyright (c) 2012-2013 Michael + * Steinert. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * A TCP socket connection. + */ + +#ifndef AMQP_TCP_SOCKET_H +#define AMQP_TCP_SOCKET_H + +#include + +AMQP_BEGIN_DECLS + +/** + * Create a new TCP socket. + * + * Call amqp_connection_close() to release socket resources. + * + * \return A new socket object or NULL if an error occurred. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +amqp_socket_t *AMQP_CALL amqp_tcp_socket_new(amqp_connection_state_t state); + +/** + * Assign an open file descriptor to a socket object. + * + * This function must not be used in conjunction with amqp_socket_open(), i.e. + * the socket connection should already be open(2) when this function is + * called. + * + * \param [in,out] self A TCP socket object. + * \param [in] sockfd An open socket descriptor. + * + * \since v0.4.0 + */ +AMQP_PUBLIC_FUNCTION +void AMQP_CALL amqp_tcp_socket_set_sockfd(amqp_socket_t *self, int sockfd); + +AMQP_END_DECLS + +#endif /* AMQP_TCP_SOCKET_H */ diff --git a/ext/librabbitmq/centos_x64/lib/librabbitmq.a b/ext/librabbitmq/centos_x64/lib/librabbitmq.a new file mode 100644 index 0000000000000000000000000000000000000000..8fc39d06b33e0639e84b1a89e789a952da66ae35 GIT binary patch literal 134844 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

J+58?aPUQ^( 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 X?B${;f(Xu~_Z`y#BmW