The NSCA-ng Protocol, Version 1
===============================

> [Holger Weiss](mailto:holger@weiss.in-berlin.de)  
> February 2013

This is an informal description of the NSCA-ng Protocol, Version 1, used for
transmitting "monitoring commands" from NSCA-ng clients to NSCA-ng servers.

The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to
be interpreted as described in [RFC 2119][1].

Connection Initiation
---------------------

The NSCA-ng server listens on TCP port 5668.  As soon as an NSCA-ng client
connects, a TLS handshake is initiated in order to establish a secure
connection.  Implementations MUST support TLS v1.0 as per [RFC 2246][2].
Also, the pre-shared key cipher suite `TLS_PSK_WITH_AES_256_CBC_SHA` as
defined in [RFC 4279][3] MUST be offered by clients and accepted by servers.
However, implementations MAY attempt to negotiate newer versions of the TLS
protocol and/or other TLS cipher suites during the TLS handshake.  When the
TLS connection is established successfully, the client can initiate the
first NSCA-ng request.  All NSCA-ng data MUST be transmitted as TLS
"application data".

NSCA-ng Session
---------------

Let's begin with an example where the client successfully transmits the
`ENABLE_NOTIFICATIONS` command to the server (`C:` and `S:` indicate lines
sent by the client and server, respectively):

    C: MOIN 1 Zm9vYmFy
    S: MOIN 1
    C: PUSH 34
    S: OKAY
    C: [1358980254] ENABLE_NOTIFICATIONS
    S: OKAY
    C: QUIT
    S: OKAY

An NSCA-ng session is a sequence of one or more request-response pairs and
zero or more "monitoring command" submissions.  Requests and responses are
CRLF-terminated lines (though implementations SHOULD also accept
LF-terminated lines).  The length of such a line MUST NOT exceed 1024
octets, including the CRLF-termination.

Requests can only be issued by clients.  A request consists of a
case-insensitive four-character keyword followed by zero or more arguments.
Keywords and arguments consist of printable US-ASCII characters, and are
each separated by a single space character.

Responses are emitted by servers and consist of a four-character keyword,
which MUST be sent in all uppercase letters.

The first request issued by the client (after establishing the TLS session)
MUST be a `MOIN`, `PING`, or `BAIL` request.  If the first request is a
`MOIN` request, the last request issued by the client MUST be a `QUIT` or
`BAIL` request.

The remaining part of this document describes the possible client requests
and server responses.  "Monitoring command" submissions are described in the
context of the `PUSH` request.

MOIN Request
------------

    Synopsis:   MOIN <version> <session-id>
    Example:    MOIN 1 Zm9vYmFy

The client issues a `MOIN` request in order to negotiate the protocol
`<version>` and to specify a `<session-id>`.

The protocol `<version>` is a positive decimal number, currently always `1`.

The `<session-id>` is an arbitrary string consisting of 2--64 printable
US-ASCII characters.  Clients SHOULD strive for uniqueness when generating
the `<session-id>`, though it's currently not referenced anywhere else in
the NSCA-ng protocol.  Implementations might mention the `<session-id>` when
logging connection data.

If a `MOIN` request is sent, it MUST be the first request of an NSCA-ng
session; except that the `MOIN` request MAY be retried with different
parameters after the server replied to a `MOIN` request with a `FAIL`
response.

On success, the server replies with a `MOIN` response.

See also: <http://en.wikipedia.org/wiki/Moin>

PING Request
------------

    Synopsis:   PING <version>
    Example:    PING 1

The protocol `<version>` is a positive decimal number, currently always `1`.

If a `PING` request is sent, it MUST be the first request of an NSCA-ng
session; except that the `PING` request MAY be retried with different
parameters after the server replied to a `PING` request with a `FAIL`
response.

On success, the server replies with a `PONG` response.  The TLS connection
is then shut down (cleanly) by both sides.

PUSH Request
------------

    Synopsis:   PUSH <size>
    Example:    PUSH 42

The client issues a `PUSH` request in order to initiate a "monitoring
command" submission.  The "monitoring command" is expected to be in the
format described in the Nagios documentation.  The trailing newline
character MUST be included, and the submitted "monitoring command" MUST NOT
be CRLF-terminated.  Newline characters within the "monitoring command"
(except for the trailing newline) MUST be replaced with the literal string
`\n`, and backslash characters MUST be escaped with another backslash.

The `<size>` parameter specifies the size of the "monitoring command" in
octets, including the trailing newline character.

On success, the server replies with an `OKAY` response.  The client then
transmits the "monitoring command".  On success, the server replies with
another `OKAY` response.

The client MUST NOT submit multiple "monitoring commands" via a single
`PUSH` request.  The client MAY issue multiple `PUSH` requests per NSCA-ng
session, though.

NOOP Request
------------

    Synopsis:   NOOP
    Example:    NOOP

A `NOOP` request has no effect, with the exception that any connection
timeout timers on the server SHOULD be reset.

On success, the server replies with an `OKAY` response.

QUIT Request
------------

    Synopsis:   QUIT
    Example:    QUIT

The client issues a `QUIT` request in order to close the NSCA-ng session.

On success, the server replies with an `OKAY` response.  The TLS connection
is then shut down (cleanly) by both sides.

BAIL Request
------------

    Synopsis:   BAIL <message> ...
    Example:    BAIL I'm feeling bad

The client may transmit a `BAIL` request for any reason at any time.  An
arbitrary, human-readable `<message>` MUST be specified.

The TLS connection is then shut down immediately and unconditionally (but
cleanly) by both sides.

MOIN Response
-------------

    Synopsis:   MOIN <version>
    Example:    MOIN 1

The server accepts a `MOIN` request by sending a `MOIN` response.  If the
server doesn't support the protocol `<version>` suggested in the client's
`MOIN` request, the server MUST either specify a supported protocol
`<version>` in the `MOIN` response or generate a `BAIL` response.  In the
former case, the client MUST either accept the protocol `<version>`
suggested in the server's `MOIN` response or generate a `BAIL` request.

The protocol `<version>` is a positive decimal number, currently always `1`.

PONG Response
-------------

    Synopsis:   PONG <version>
    Example:    PONG 1

The server replies to a `PING` request with a `PONG` response.

The protocol `<version>` is a positive decimal number, currently always `1`.

The TLS connection is then shut down (cleanly) by both sides.

OKAY Response
-------------

    Synopsis:   OKAY
    Example:    OKAY

The server acknowledges the current client request or "monitoring command"
submission by sending an `OKAY` response.

FAIL Response
-------------

    Synopsis:   FAIL <message> ...
    Example:    FAIL You're not authorized to submit this command

The server sends a `FAIL` response to reject the current client request or
"monitoring command" submission.  An arbitrary, human-readable `<message>`
MUST be specified.

The client then sends a new request.

BAIL Response
-------------

    Synopsis:   BAIL <message> ...
    Example:    BAIL I'm feeling horrible

The server may transmit a `BAIL` response for any reason at any time.  An
arbitrary, human-readable `<message>` MUST be specified.

The TLS connection is then shut down immediately and unconditionally (but
cleanly) by both sides.

[1]: http://tools.ietf.org/html/rfc2119 "RFC 2119"
[2]: http://tools.ietf.org/html/rfc2246 "RFC 2246"
[3]: http://tools.ietf.org/html/rfc4279 "RFC 4279"

<!-- vim:set filetype=markdown textwidth=76 joinspaces: -->
