## Synchronization protocol ¶

So-called synchronization protocol (SP) is used in current TCP daemon’s implementation. It is used for synchronizing spool directory contents between two nodes.

It is aimed to be very simple and effective. It uses reliable transport like TCP connections. It must be effective both on single-duplex and full-duplex links: for example satellites have very high throughput but high-delay links, so acknowledging of each received packet, like XMODEM does, causes unacceptable performance degradation.

Internally it uses various timeouts and deadlines. One of them used extensively is 10 seconds default deadline timeout. You can override it with `$NNCPDEADLINE` environment variable, that could be useful with very high delay links.

SP works on top of `Noise_IK_25519_ChaChaPoly_BLAKE2b` protocol. Each Noise packet is sent inside an XDR envelope:

    +-----------------+
    | MAGIC | PAYLOAD |
    +-----------------+

| XDR type | Value
--- | --- | ---
Magic number | 8-byte, fixed length opaque data | `N N C P S 0x00 0x00 0x01`
Payload | variable length opaque data | Noise packet itself

Peers static keys are specified as noisepub configuration entry.

Payload inside Noise packets has maximum size of 64 KiB - 256 B = 65280 B. It is sent immediately in the first message by each side. The very first payload (that is carried inside handshake messages) is always padded to the maximum size with HALT packets (read below), for hiding actual number of INFO packets (number of files available for transmission).

Each SP payload is a concatenation of SP packets. Each packet has XDR-encoded header and then corresponding XDR-encoded body. Header is just an unsigned integer telling what body structure follows.

HALT ¶

  Stop file transmission, empty sending queue on the remote side. Actually HALT packet does not have any body, only the header with the type. It is also used in the first payload for padding to the maximum size.

      +------+
      | HALT |
      +------+

PING ¶

  Dummy packet only used for determining workability of the connection.

      +------+
      | PING |
      +------+

INFO ¶

  Information about the file we have for transmission.

      +------+--------------------+
      | INFO | NICE | SIZE | HASH |
      +------+--------------------+

  | XDR type | Value
  --- | --- | ---
  Niceness | unsigned integer | 1-255, file niceness level
  Size | unsigned hyper integer | File size
  Hash | 32-byte, fixed length opaque data | Unique file identifier, its checksum

FREQ ¶

  File transmission request. Ask remote side to queue the file for transmission.

      +------+---------------+
      | FREQ | HASH | OFFSET |
      +------+---------------+

  | XDR type | Value
  --- | --- | ---
  Hash | 32-byte, fixed length opaque data | Unique file identifier, its checksum
  Offset | unsigned hyper integer | Offset from which remote side must transmit the file

FILE ¶

  Chunk of file.

      +------+-------------------------+
      | FILE | HASH | OFFSET | PAYLOAD |
      +------+-------------------------+

  | XDR type | Value
  --- | --- | ---
  Hash | 32-byte, fixed length opaque data | Unique file identifier, its checksum
  Offset | unsigned hyper integer | Offset from which transmission goes
  Payload | variable length opaque data | Chunk of file itself

DONE ¶

  Signal remote side that we have successfully downloaded the file.

      +------+------+
      | DONE | HASH |
      +------+------+

  | XDR type | Value
  --- | --- | ---
  Hash | 32-byte, fixed length opaque data | Unique file identifier, its checksum

Typical peer’s behaviour is following:

         ┌─────────┐                       ┌─────────┐
         │Initiator│                       │Responder│
         └────┬────┘                       └────┬────┘
              │                                 │
              │         ╔═════════════╗         │
    ══════════╪═════════╣ preparation ╠═════════╪══════════
              │         ╚═════════════╝         │
              │                                 │
              │              [s]                │
              │<────────────────────────────────│
              │                                 │
              │                                 │
              │         ╔═════════════╗         │
    ══════════╪═════════╣ interactive ╠═════════╪══════════
              │         ╚═════════════╝         │
              │                                 │
              │[e, es, s, ss], INFO..., HALT... │
              │────────────────────────────────>│
              │                                 │
              │ [e, ee, se], INFO..., HALT...   │
              │<────────────────────────────────│
              │                                 │
              │   INFO..., FREQ..., DONE...     │
              │────────────────────────────────>│
              │                                 │
              │   INFO..., FREQ..., DONE...     │
              │<────────────────────────────────│
              │                                 │
              │FILE..., INFO..., DONE..., PING  │
              │────────────────────────────────>│
              │                                 │
              │FILE..., INFO..., DONE..., PING  │
              │<────────────────────────────────│
              │                                 │
              │                                 │

1. Perform Noise-IK handshake:
   Initiator

     Collects all tx-related files information and prepares payload filled with INFOs for including in the first handshake message.

   Responder

     After receiving the first handshake message, it gains remote identity knowledge and similarly prepares the payload for including in the second handshake message.

   All payloads are padded to maximal message size with HALTs.

2. If queued INFOs are not sent completely in handshake payloads, then send all of remaining in the transport stage.
3. When INFO packet received:
   - Check that it has an acceptable niceness level. Ignore it if it is too nice.
   - If already downloaded file exists, then queue DONE sending.
   - If `seen/XXX` exists, then queue DONE sending.
   - If `.part` exists, then queue FREQ sending with corresponding offset.
4. When FREQ packet received, insert it to current sending queue with niceness level sort: higher priority packets will be sent first. Sending queue contains files with offsets that are needed to be sent.
5. While sending queue is not empty, send FILE packets. FREQ could contain offset equal to size – anyway sent FILE packet with an empty payload. FILE sending is performed only if no other outgoing packets are queued: INFOs have higher priority.
6. When FILE packet received, check if it is completely downloaded (comparing to INFO’s packet size information). If so, then run background integrity checker on it. If check succeeds, then delete `.part` suffix from file’s name and send DONE packet.
7. When DONE packet received, delete corresponding file.
8. When HALT packet received, empty file sending queue.
9. Each second, node checks: are there any new tx packets appeared and queues corresponding INFO packets.
10. Each minute, if no packets were sent, node sends PING packet.
11. If no non-PING packets are sent and received during onlinedeadline duration, then close the connection. There is no explicit indication that session is over.
12. If no packets are received during two minutes (two PING timeouts), then close the connection.