You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

344 lines
11 KiB
C

/***************************************************************************
* Copyright (C) gempa GmbH *
* All rights reserved. *
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
* *
* Author: Jan Becker *
* Email: jabe@gempa.de *
* *
* GNU Affero General Public License Usage *
* This file may be used under the terms of the GNU Affero *
* Public License version 3.0 as published by the Free Software Foundation *
* and appearing in the file LICENSE included in the packaging of this *
* file. Please review the following information to ensure the GNU Affero *
* Public License version 3.0 requirements will be met: *
* https://www.gnu.org/licenses/agpl-3.0.html. *
* *
* Other Usage *
* Alternatively, this file may be used in accordance with the terms and *
* conditions contained in a signed written agreement between you and *
* gempa GmbH. *
***************************************************************************/
#ifndef GEMPA_BROKER_PROTOCOL_H__
#define GEMPA_BROKER_PROTOCOL_H__
namespace Seiscomp {
namespace Messaging {
namespace Broker {
namespace Protocol {
// Defines do not make much sense inside namespaces but they are placed here
// to stay close to future variable declarations.
/**
* It follows a list of definitions for all protocol commands and replies and
* their headers. They are being used in the code and changing them here will
* cause a change in behaviour of the server.
*/
/**
* ```
* CONNECT
* Ack-Window: [number of messages after which an ack will be send from the server]
* Membership-Info: 1
* Queue: [name of queue]
* Client-Name: [name of client]
* Subscriptions: [list of groups]
* Seq-No: [last seen sequence number]
*
* ^@
* ```
*
* The *Seq-No* header contains the last sequence number the client has seen from
* that queue. That header is optional. If subscriptions are given then the
* client will receive an **ENTER** frame for each group it subscribed to. If any
* of the requested groups does not exist, an **ERROR** frame is sent and the
* connection is closed.
*
* The order of messages looks as follows:
*
* 1. CONNECT
* 2. CONNECTED
* 3. ENTER
* 4. RECV
*
* Step 3 repeats for as many groups as given in the subscription list. Step 4
* repeats for all messages received during the lifetime of the connection.
*/
#define SCMP_PROTO_CMD_CONNECT "CONNECT"
#define SCMP_PROTO_CMD_CONNECT_HEADER_QUEUE "Queue"
#define SCMP_PROTO_CMD_CONNECT_HEADER_CLIENT_NAME "Client-Name"
#define SCMP_PROTO_CMD_CONNECT_HEADER_MEMBERSHIP_INFO "Membership-Info"
#define SCMP_PROTO_CMD_CONNECT_HEADER_SELF_DISCARD "Self-Discard"
#define SCMP_PROTO_CMD_CONNECT_HEADER_ACK_WINDOW "Ack-Window"
#define SCMP_PROTO_CMD_CONNECT_HEADER_SEQ_NUMBER "Seq-No"
#define SCMP_PROTO_CMD_CONNECT_HEADER_SUBSCRIPTIONS "Subscriptions"
/**
* ```
* DISCONNECT
* Receipt: [id]
*
* ^@
* ```
*
* The DISCONNECT command ask the server to gracefully shutdown the connection
* and free all associated resources.
*/
#define SCMP_PROTO_CMD_DISCONNECT "DISCONNECT"
#define SCMP_PROTO_CMD_DISCONNECT_HEADER_RECEIPT "Receipt"
/**
* ```
* SUBSCRIBE
* Groups: [list of groups]
*
* ^@
* ```
* Subscribes to a specific group which must exist on the server. In response
* either an **ENTER** or **ERROR** frame will be received.
*/
#define SCMP_PROTO_CMD_SUBSCRIBE "SUBSCRIBE"
#define SCMP_PROTO_CMD_SUBSCRIBE_HEADER_GROUPS "Groups"
/**
* ```
* UNSUBSCRIBE
* Groups: [list of groups]
*
* ^@
* ```
*
* Unsubscribes from a specific group which must exist on the server. In
* response either a **LEAVE** or **ERROR** frame will be received.
*/
#define SCMP_PROTO_CMD_UNSUBSCRIBE "UNSUBSCRIBE"
#define SCMP_PROTO_CMD_UNSUBSCRIBE_HEADER_GROUPS SCMP_PROTO_CMD_SUBSCRIBE_HEADER_GROUPS
/**
* Sends a message to a group or a client (peer-to-peer).
*
* ```
* SEND
* D: [name of group or the client]
* T: [MIME type]
* E: [transfer encoding]
* L: [length of content]
*
* [payload]^@
* ```
*
* Each message sent will increase the private sequence number counter for this
* connection starting with 0. So the first message will get assigned the
* sequence number 1. That counter must be maintained by the client and the
* server to correctly synchronize acknowledgements. If the message is rejected
* an **ERROR** frame will be sent to the client and the connection will be
* closed.
*/
#define SCMP_PROTO_CMD_SEND "SEND"
#define SCMP_PROTO_CMD_SEND_HEADER_DESTINATION "D"
#define SCMP_PROTO_CMD_SEND_HEADER_CONTENT_LENGTH "L"
#define SCMP_PROTO_CMD_SEND_HEADER_ENCODING "E"
#define SCMP_PROTO_CMD_SEND_HEADER_MIMETYPE "T"
#define SCMP_PROTO_CMD_SEND_HEADER_TRANSIENT "Transient"
/**
* A member notifies the server about its state including memory consumption,
* cpu usage, uptime and so on. The payload is always a key-value list
* separated by '&'.
*
* ```
* STATE
* D: [name of group or the client]
* L: [length of content]
*
* hostname=localhost&totalmemory=8589934592&clientmemoryusage=68891443...^@
* ```
*/
#define SCMP_PROTO_CMD_STATE "STATE"
#define SCMP_PROTO_CMD_STATE_HEADER_DESTINATION "D"
#define SCMP_PROTO_CMD_STATE_HEADER_CONTENT_LENGTH "L"
#define SCMP_PROTO_CMD_FIRST_CHARS "CDSU"
/**
* ```
* CONNECTED
* Queue: [name of queue]
* Server: SeisComP/2017.334
* Version: [server protocol version]
* Client-Name: [client name, either auto assigned or requested by the client]
* Authentication: [16 byte hex random NaCL nonce prefix]
* [32 byte hex NaCL public server key]
* [16 byte hex encrypted buffer: "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"]
* Groups: [list of available groups]
*
* ^@
* ```
*
* In return to a **CONNECT** frame the server responds with a **CONNECTED**
* frame. It reports the client name in use for this connection and a list of
* available groups.
*/
#define SCMP_PROTO_REPLY_CONNECT "CONNECTED"
#define SCMP_PROTO_REPLY_CONNECT_HEADER_VERSION "Version"
#define SCMP_PROTO_REPLY_CONNECT_HEADER_SCHEMA_VERSION "Schema-Version"
#define SCMP_PROTO_REPLY_CONNECT_HEADER_QUEUE SCMP_PROTO_CMD_CONNECT_HEADER_QUEUE
#define SCMP_PROTO_REPLY_CONNECT_HEADER_CLIENT_NAME SCMP_PROTO_CMD_CONNECT_HEADER_CLIENT_NAME
#define SCMP_PROTO_REPLY_CONNECT_HEADER_ACK_WINDOW SCMP_PROTO_CMD_CONNECT_HEADER_ACK_WINDOW
#define SCMP_PROTO_REPLY_CONNECT_HEADER_GROUPS "Groups"
/**
* The probably most important part of the protocol is receiving a message from
* a group or a client (peer-to-peer).
*
* ```
* RECV
* C: [client name of sender]
* D: [name of group or the client]
* T: [MIME type]
* E: [transfer encoding]
* N: [message sequence number]
* L: [length of content]
*
* [payload]^@
* ```
*
* The payload can be anything, binary data or text. Optionally the *Content-Type*
* header is set to inform the client about the format.
*/
#define SCMP_PROTO_REPLY_SEND "RECV"
#define SCMP_PROTO_REPLY_SEND_HEADER_SENDER "C"
#define SCMP_PROTO_REPLY_SEND_HEADER_SEQ_NUMBER "N"
#define SCMP_PROTO_REPLY_SEND_HEADER_DESTINATION SCMP_PROTO_CMD_SEND_HEADER_DESTINATION
#define SCMP_PROTO_REPLY_SEND_HEADER_CONTENT_LENGTH SCMP_PROTO_CMD_SEND_HEADER_CONTENT_LENGTH
#define SCMP_PROTO_REPLY_SEND_HEADER_ENCODING SCMP_PROTO_CMD_SEND_HEADER_ENCODING
#define SCMP_PROTO_REPLY_SEND_HEADER_MIMETYPE SCMP_PROTO_CMD_SEND_HEADER_MIMETYPE
/**
* ```
* ACK
* N: [connection specific sequence number]
*
* ^@
* ```
*
* The server sends according to the configured acknoledgement window an
* acknowledgement frame to signal that all messages prior to the given sequence
* number have been processed and that the current sequence number is expected
* to be the one sent. It will do that as well after 1 second the client
* hasn't sent any further messages.
*/
#define SCMP_PROTO_REPLY_ACK "ACK"
#define SCMP_PROTO_REPLY_ACK_HEADER_SEQ_NUMBER SCMP_PROTO_REPLY_SEND_HEADER_SEQ_NUMBER
/**
* ```
* RECEIPT
* Receipt-Id: [id]
*
* ^@
* ```
*
* A receipt can basically be sent for anything which has an id. A receipt is
* being sent definitely after a disconnect request. In that case the receipt
* id is the username.
*/
#define SCMP_PROTO_REPLY_RECEIPT "RECEIPT"
#define SCMP_PROTO_REPLY_RECEIPT_HEADER_ID "Receipt-Id"
/**
* A members enters a group. In response to a **SUBSCRIBE** command, the complete
* group information will be sent to the client. Specifically if
* ```Member == self```. Otherwise only the group and member information will be
* sent from the server to all clients that are subscribed to that group. The
* client needs to update its internal cache and the frame body is empty in that
* case.
*
* ```
* ENTER
* D: [name of group]
* C: [name of client]
*
* clientA, clientB, ...
* }^@
* ```
*/
#define SCMP_PROTO_REPLY_ENTER "ENTER"
#define SCMP_PROTO_REPLY_ENTER_HEADER_GROUP "D"
#define SCMP_PROTO_REPLY_ENTER_HEADER_MEMBER "C"
/**
* A member leaves a group. This message will sent from the server to all clients
* that are subscribed to the group in question.
*
* ```
* LEAVE
* D: [name of group]
* C: [name of client]
*
* ^@
* ```
*/
#define SCMP_PROTO_REPLY_LEAVE "LEAVE"
#define SCMP_PROTO_REPLY_LEAVE_HEADER_GROUP SCMP_PROTO_REPLY_ENTER_HEADER_GROUP
#define SCMP_PROTO_REPLY_LEAVE_HEADER_MEMBER SCMP_PROTO_REPLY_ENTER_HEADER_MEMBER
/**
* A member state of health information or simply its state including
* memory consumption, cpu usage, uptime and so on. The payload is always
* a key-value list separated by '&'.
*
* ```
* STATE
* L: [length of content]
* D: [name of group or the client]
* C: [name of client]
*
* hostname=localhost&totalmemory=8589934592&clientmemoryusage=68891443...^@
* ```
*/
#define SCMP_PROTO_REPLY_STATE "STATE"
#define SCMP_PROTO_REPLY_STATE_HEADER_DESTINATION "D"
#define SCMP_PROTO_REPLY_STATE_HEADER_CLIENT "C"
#define SCMP_PROTO_REPLY_STATE_HEADER_CONTENT_LENGTH SCMP_PROTO_CMD_SEND_HEADER_CONTENT_LENGTH
/**
* A client was disconnected. This message will sent from the server to all
* clients currently connected.
*
* ```
* DISCONNECTED
* C: [name of client]
*
* ^@
* ```
*/
#define SCMP_PROTO_REPLY_DISCONNECTED "DISCONNECTED"
#define SCMP_PROTO_REPLY_DISCONNECTED_HEADER_CLIENT SCMP_PROTO_REPLY_STATE_HEADER_CLIENT
/**
* ```
* ERROR
* N: [connection specific sequence number]
*
* Error message ...^@
* ```
*/
#define SCMP_PROTO_REPLY_ERROR "ERROR"
#define SCMP_PROTO_REPLY_ERROR_HEADER_SEQ_NUMBER SCMP_PROTO_REPLY_SEND_HEADER_SEQ_NUMBER
}
}
}
}
#endif