AnyEvent-Porttracker
view release on metacpan or search on metacpan
Porttracker/protocol.pod view on Meta::CPAN
=head1 DESCRIPTION
This document describes the porttracker API for third-party programs to
use (it is also used internally to communicate with the tawnyd).
=head1 CONVENTIONS
In this document, command names, paths and similar entities are F<formatted like this>.
Preformatted sections are indented like this. This is used for verbatim
text. Portions of the section that need to be replaced by dynamic
content are enclosed in <angle brackets>.
< Lines starting with "< " are received from the server.
> Lines starting with "> " are sent to the server. # and this is a comment
Both text refering to these variable sections and verbatim text inside
other paragraphs is formatted C<like this>.
=head1 OVERVIEW
=head2 SOCKET LAYER
The API uses a tcp connection to port 55 on the porttracker management
machine. The TCP connection must be 8-bit-clean (as UTF-8 is used as
character encoding) and can be driven either in binary or text mode.
Alternatively, the server also listens on the Unix socket
F</tmp/.tawny/.tawnyd> for local connections (where "none" is one of the
guaranteed auth methods).
There are currently no timeouts for the connection itself, but TCP
keepalive might be enabled server-side.
=head2 PACKAGE ENCAPSULATION LAYER
The protocol is based on sending and receiving JSON arrays encoded as
UTF-8. The server expects JSON arrays to be sent back-to-back, without any
separators, but for testing purposes it is often convenient to end JSON
arrays with ASCII LF (or ASCII CR LF) characters ("newline"), effectively
treating it as a line-based protocol.
To support programming languages without incremental JSON parsers,
the server will append an ASCII LF character to each JSON array and
additionally will make sure that its replies will never contain any ASCII
LF characters, so instead of directly parsing the JSON stream, the client
may also read single lines and then decode the JSON array contained in
each line.
Note 1: This means that one can use C<telnet> or a similar program to test
the protocol, as the server ignores ASCII CR and LF characters but sends
its responses as single lines.
Note 2: There are two principal parsing strategies: the obvious one is to
read a single (potentially very large) line and then decode it, and the
less obvious one is to use a streaming parser and simply read JSON arrays
one after each other.
=head2 MESSAGE LAYER
Server and client can send messages to each other at any time (usually the
client first has to wait and parse the initial server greeting, though, to
see what kind of authentication is required).
All messages are JSON arrays in one of the following formats:
[<id>, <type>, <args...>] # client request
[<id>, <status>, <args...>] # server response
[null, <type>, <args...>] # server notification
The first member, C<id>, identifies the request/response pair: Each
request the client sends has to use a unique ID not currently in use
by any request that is still ongoing. Any string or number can be
used for the C<id> value. The C<type> member is a string indicating
the type of request to the server. The remaining members (if any) are
request-specific.
Each server response to a request will use the same C<id> value as the
request. The second member, C<status>, is either C<0> for failure,
followed by an error message and optionally more information, or C<1> for
success and request-specific return values.
The protocol supports pipelining (sending multiple requests without
processing any replies) and responses to a request can come in any
order. Most requests will be handled in parallel, only some (like the
login messages) are guaranteed to get processed in order.
If the first member is the JSON C<null> value, then the message is a
server notification and the C<type> member identified the notification
type. This mechanism is used for the initial server greeting and any fatal
errors (such as wrongly formatted client requests).
Note: The type model used for JSON is "soft", that is, numbers might
sometimes be returned as strings, and vice versa. The only values in the
protocol where you can be sure of the type are the C<id> and status return
values, for other values you have to be liberal in what you accept.
=head1 SESSION STRUCTURE
When connecting, the server sends a server greeting notification
("hello"), informing the client of the protocol version, whether
authentication is required and which kind of authentication is supported.
If the server indicated that authentication is required, the client will
then have to send login requests until it successfully authenticated.
After that, the server will continue serving client requests.
To end a session, the client just should simply drop the connection.
=head1 EXAMPLE SESSION
< [null,"hello",1,["login"]]
Server sent the initial greeting and requests the
( run in 1.148 second using v1.01-cache-2.11-cpan-140bd7fdf52 )