This is an old revision of the document!
Table of Contents
Protocol
This document is still a draft, and is subject to change at any time!
The PawSD protocol is designed around a simple request-response architecture that allows it to work over a variety of underlying transports. All a transport has to provide is a way for a client to send some bytes to a server and for the server to send some bytes back in response. It is imperative to choose transports that provide some form of data integrity, i.e. preventing malicious third parties from modifying data in-transit between the client and server.
Unless otherwise specified, the protocol uses big-endian byte and bit order, and no padding.
Within this document, integers are described in a shorthand format: a letter “u” for unsigned or “s” for signed, followed by their length in bits. “Enums” are unsigned integers that take one of a defined set of values. Arrays are indicated by prefixing their item type with the number of items in square brackets, or an underscore if it's variable: [16]u8 means 16 arbitrary bytes and [_]record means a number of records specified by a previous field.
Requests and responses
A request is structured as follows:
| Field | Length | Type |
|---|---|---|
| request magic | 8 bytes | constant ASCII string “PawRqust” |
| protocol version | 2 bytes | u16 (current version is 1) |
| request verb | 2 bytes | enum |
| request payload | varies | according to verb |
And a response looks like this:
| Field | Length | Type |
|---|---|---|
| response magic | 8 bytes | constant ASCII string “PawRspns” |
| protocol version | 2 bytes | u16 (current version is 1) |
| status code | 2 bytes | enum |
| response payload | varies | according to status code |
For all status codes except “OK”, the response payload is a string (2 byte length prefix, UTF-8, no null terminator) describing the error in a manner useful to client developers. Friendly user interfaces are expected to provide their own localised descriptions of errors, but may choose to also show the server's description.
Status codes
The currently defined status codes for responses are (in hexadecimal):
- 0x0200: OK
- 0x0400: generic client error
- 0x0401–0x0403: TODO
- 0x0404: resource not found
- 0x0500: generic server error
- 0x0501: not implemented
- 0x0503: service temporarily unavailable
- 0x0505: unknown verb
Zones, services and records
Zones are purely logical and are not literally sent over the wire. However, services are identified by the combination of their containing zone's public key (and its type/cryptosystem) along with their index within the zone (starting from 0 for the “metadata service” containing info about the zone itself).
Services are transmitted as follows:
| Field | Length | Type |
|---|---|---|
| signature length | 2 bytes | u16 |
| signature | varies | [_]u8 |
| index | 2 bytes | u16 |
| flags | 4 bytes | bitfield |
| record count | 2 bytes | u16 |
| records | varies | [_]record |
The signature is calculated from the concatenation of the index, flags, record count, and records fields (i.e. the entire service in wire format except for the signature itself). The signature algorithm is not given in the service itself but will be specified as part of the service's identifier, such as when requesting it.
Records are just a list of tag-value pairs:
| Field | Length | Type |
|---|---|---|
| tag count | 2 bytes | u16 |
| tag1 | 16 bytes | [2]u64 |
| value1 length | 4 bytes | u32 |
| value1 | varies | [_]u8 |
| tag2, etc |
Signature algorithms
The only currently defined signature algorithm (or “public key type”) is Ed25519 (identified on the wire by u16 “25519”). All implementations are required to support it, and shouldn't implement any other algorithms except for testing purposes. This is the “pure” variant usually called ed25519 in crypto libraries, not “pre-hashed” (ed25519ph).
Verb 0: Echo
This is intended for troubleshooting purposes only. The server simply returns the same data back to the client.
Request and response payloads (identical):
| Field | Length | Type |
|---|---|---|
| data | 16 bytes | [16]u8 |
Verb 1: Fetch service
The client asks the server for a particular service. Even if the service exists, the server may not have it, in which case it should respond “resource not found” (and should not perform any lookups of its own to try to find it).
Request payload:
| Field | Length | Type |
|---|---|---|
| public key type | 2 bytes | enum |
| public key length | 2 bytes | u16 |
| public key | varies | [_]u8 |
| service index | 2 bytes | u16 |
Response payload:
| Field | Length | Type |
|---|---|---|
| service | varies | service |
TODO: other verbs!
