Skip to content

Instantly share code, notes, and snippets.

@vinz243
Last active August 18, 2018 19:33
Show Gist options
  • Save vinz243/e79b631ec6a726b42884fd54618e0d2c to your computer and use it in GitHub Desktop.
Save vinz243/e79b631ec6a726b42884fd54618e0d2c to your computer and use it in GitHub Desktop.
Fjord Protocol Specifications 1.0

Overview

Fjord Protocol is a TCP based protocol that allows a more flexible and adaptable sharing of pieces between a server that acts as a buffer and a client which will receive all informations about the server state as well as the downloaded pieces as soon as they are available.

Protocol version: 1.0.0

note: big-endian is the norm here

1. Server implementation

The most basic TCP server should

  • allow the connection of new clients through a handshake message and verify the handshake token with its own secret.
  • allow authenticated wires to upload a torrent file and directly start downloading it to a local directory
  • allow authenticated wires to selectively listen to torrent-specific events, using bitmasks
    • receive status update including eta, speeds
    • receive piece availabilities
    • receive pieces
  • allow authenticated to start, resume and destroy torrents

A client is a host that is defined by a host ID (randomly generated by the server and specified in the handshake), and remote server address. A wire is a connection between the client and the server, defined by:

  • its client ID. Basically the host ID.
  • the target server address
  • the client port listening for connection

So there might be only one client per client/server relation (as expected) but several wires for a client.

2. Specifications

2.1. Messages

Every message is structured like this:

01 A4 <Message Length: UInt32 (4)> <Message Type: UInt8 (1)> <Data>

The first bytes are a constant value to identify protocol used (c. f. http://www.bittorrent.org/beps/bep_0003.html#peer-protocol)

The message length represents the total message length in bytes, from 0 to 4,294,967,295. This includes the message prefix (0x14A), the message length and type as well as the total amount of data.

The client-to-server message types are defined as follows:

  • 0x01: Handshake message
  • 0x03: Subscribe to server-specific events
  • 0x04: Start a torrent
  • 0x05: Subscribe to torrent specific events
  • 0x07: Torrent-specific commands
  • 0x08: Request one or more pieces

The server may respond with these messages:

  • 0x02: Handshake Response message
  • 0x06: Server-specific events notifications
  • 0x0a: Torrent specific events
  • 0x10: Piece data

2.1.1. Handshake Message

The handshake is the first message that should be sent by the client to the server. The only data it contains is an UTF-8 encoded authentication JWT token that allows only selected peers to connect to the server. This token, signed and delivered by the server should contains two values :

  • hi the client ID, a randomly generated number
  • hn the client name a familiar name for the user

The said token should expire at most 3 months after its creation.

2.1.2. Subscribe to server-specific events

This message is used by clients to listen for server-specific events. Those are:

The message sent by the client to the server in order to subscribe to events is defined like this:

<…> <Event Bitmask: UInt8 (1)>

The event bitmask is a simple integer which specifies which events to listen to for this wire. Possible values are available in section 2.3.1

2.1.3 Start torrent

The start torrent message is a simple message which data only contains the torrent file buffer to start.

2.1.4 Subscribe to torrent events

This event has payload defined like this:

<…> <Hash: UInt (20)> <Event mask: UInt8 (1)>

The hash is the infoHash this wires wants to listen to event. The event bitmask selects which event to subscribe to, by masking bits using &. Possible events are available in 2.3.2. Torrent events

Note: all the events are distributed across clients, so one client with multiple wires having same event bitmasks will only receive every notification once.

2.1.5. Torrent specific commands

Issues torrent specific commands. Payload is:

<…> <Command ID: UInt8 (1)> [Command payload]

For possible commands see 2.3.3. Torrent commands

2.1.6. Requesting pieces

This commands request pieces for this wire as soon as they are available and the wire is not already transmitting data.

<…> <Torrent hash: string (20)> <Pieces Indexes: UInt32 (4)>...

2.2 Server-emitted events

2.2.1 Handshake Response message

Once a Handshake message has been sent to the server, the latter will respond with a Handshake response message that specifies whether the authentication request has been accepted - essentially if the JWT token is valid. If it fails, it may also contain an error message and the connection will eventually be dropped by the server.

The response data is as follows:

… <Status byte: UInt8 (1)> [Error Message: string (…)]

The Status byte is either 0 (failure) or 1 (success). If it failed to authenticate, then the error message is an UTF-8 encoded string for the remaining data.

2.2.2 Server-specific events notifications

The payload is:

<…> <Event: UInt8 (1)> <Event payload>

See section 2.3.1 for possible events and their corresponding payloads.

2.2.3 Torrent event

The payload is

<…> <Event: UInt8 (1)> <Info Hash: UInt (20)> <Event payload>

See Torrent events for a list of events and payloads

2.2.4 Torrent piece

The payload is:

<…> <Torrent hash: string (20)> <Piece Index: UInt32 (4)> <Piece data...>

See section 2.3.1 for possible events and their corresponding payloads.

2.3 Definitions

2.3.1 Server events

  • 0x01: torrent started. Data is the torrent infoHash encoded as an UTF-8 string.
  • 0x02: torrent finished. Data is the torrent infoHash.
  • 0x04: peer connected. Data is <…> <Host ID: string (8)> <Host name: string (…)>

2.3.2 Torrent events

  • 0x01: Torrent started
  • 0x02: Torrent status update. Payload for the callback is:
<…> 
  <Torrent status: UInt8 (2)>
  <Peers connected: UInt8 (2)>
  <Downloaded: UInt32 (4)>
  <Uploaded: UInt32 (4)>
  <Download speed: UInt32 (4)>
  <Upload speed: UInt32 (4)>
  • 0x04: Torrent piece available. Payload is a UInt32Array describing grouped indexes of new pieces received

2.3.3 Torrent commands

  • 0x01: Pause torrent
  • 0x02: Resume torrent
  • 0x03: Destroy torrent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment