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