mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-09 13:10:25 +00:00
264 lines
5.9 KiB
Plaintext
264 lines
5.9 KiB
Plaintext
|
|
LLARP Traffic Routing Protocol (LTRP)
|
|
|
|
LRTP is a protocol that instructs how to route hidden service traffic on LLARP
|
|
based networks.
|
|
|
|
The key words "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 [RFC2119].
|
|
|
|
Overview:
|
|
|
|
LRTP is a message oriented data delivery and receival protocol for hidden
|
|
service traffic. All structures are BitTorrent Encoded dictionaries sent
|
|
over TCP.
|
|
|
|
all structures are bencoded when sent over the networks.
|
|
In this document they are provided in JSON for ease of display.
|
|
|
|
message format:
|
|
|
|
<2 bytes length (N)>
|
|
<N bytes of data>
|
|
|
|
|
|
Nouns (data structures):
|
|
|
|
Path: information about a path that we have built
|
|
|
|
{
|
|
H: [router_id_32_bytes, router_id_32_bytes, router_id_32_bytes, router_id_32_bytes],
|
|
R: "<16 bytes local rxid>",
|
|
T: "<16 bytes local txid>"
|
|
}
|
|
|
|
Introduction: a hidden service introduction
|
|
|
|
{
|
|
E: expiration_ms_since_epoch_uint64,
|
|
L: advertised_latency_ms_uint64,
|
|
P: "<16 bytes pathid>",
|
|
R: "<32 bytes RouterID>"
|
|
}
|
|
|
|
ServiceInfo: public key info for hidden service address
|
|
|
|
{
|
|
A: "<32 bytes .loki address>",
|
|
E: "<32 bytes public encryption key>",
|
|
S: "<32 bytes public signing key>"
|
|
}
|
|
|
|
IntroSet: information about an introduction set from the network
|
|
|
|
{
|
|
E: expires_at_timestamp_ms_since_epoch_uint64,
|
|
I: [Intro0, Intro1, ... IntroN],
|
|
S: ServiceInfo
|
|
}
|
|
|
|
Converstation: information about a loki network converstation
|
|
|
|
{
|
|
L: "<32 bytes loki address provided if a loki address>",
|
|
S: "<32 bytes snode address provided if a snode address>",
|
|
T: "<16 bytes convo tag>"
|
|
}
|
|
|
|
SessionInfo: information about our current session
|
|
|
|
{
|
|
I: [inbound,convos,here],
|
|
O: [outbound,covos,here],
|
|
P: [Path0, Path1, .... PathN],
|
|
S: Current IntroSet,
|
|
}
|
|
|
|
Verbs (methods):
|
|
|
|
session requset (C->S)
|
|
|
|
the first message sent by the client
|
|
|
|
{
|
|
A: "session",
|
|
B: "<8 bytes random>",
|
|
T: milliseconds_since_epoch_client_now_uint64,
|
|
Y: 0,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
session accept (S->C)
|
|
|
|
sent in reply to a session message to indicate session accept and give
|
|
a session cookie to the client.
|
|
|
|
{
|
|
A: "session-reply",
|
|
B: "<8 bytes random from session request>",
|
|
C: "<16 bytes session cookie>",
|
|
T: milliseconds_since_epoch_server_now_uint64,
|
|
Y: 0,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
session reject (S->C)
|
|
|
|
sent in reply to a session message to indicate session rejection
|
|
|
|
{
|
|
A: "session-reject",
|
|
B: "<8 bytes random from session request>",
|
|
R: "<variable length utf-8 encoded bytes human readable reason here>",
|
|
T: milliseconds_since_epoch_server_now_uint64,
|
|
Y: 0,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
spawn a hidden service (C->S)
|
|
|
|
only one hidden service can be made per session
|
|
|
|
{
|
|
A: "spawn",
|
|
C: "<16 bytes session cookie>",
|
|
O: config_options_dict,
|
|
Y: 1,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
inform that we have spawned a new hidden service endpoint (S->C)
|
|
|
|
{
|
|
A: "spawn-reply",
|
|
C: "<16 bytes session cookie>",
|
|
S: ServiceInfo,
|
|
Y: 1,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
inform that we have not spaned a new hidden service endpint (S->C)
|
|
|
|
after sending this message the server closes the connection
|
|
|
|
{
|
|
A: "spawn-reject",
|
|
C: "<16 bytes session cookie>",
|
|
E: "<error message goes here>",
|
|
Y: 1,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
create a new convseration on a loki/snode address (C->S)
|
|
|
|
{
|
|
A: "start-convo",
|
|
B: "<8 bytes random>",
|
|
C: "<16 bytes session cookie>",
|
|
R: "human readable remote address .snode/.loki",
|
|
Y: sequence_num_uint64,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
sent in reply to a make-convo message to indicate rejection (S->C)
|
|
|
|
{
|
|
A: "start-convo-reject",
|
|
B: "<8 bytes random from start-convo message>",
|
|
C: "<16 bytes session cookie>",
|
|
S: status_bitmask_uint,
|
|
Y: sequence_num_uint64,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
sent in reply to a make-convo message to indicate that we have accepted this
|
|
new conversation and gives the convo tag it uses.
|
|
|
|
{
|
|
A: "start-convo-accept",
|
|
B: "<8 bytes random from start-convo message>",
|
|
C: "<16 bytes session cookie>",
|
|
Y: sequence_num_uint64,
|
|
Z: "<32 bytes keyed hash>
|
|
}
|
|
|
|
infrom the status of a converstation on a loki address (S->C)
|
|
|
|
for an outbund conversation it is sent every time the status bitmask changes.
|
|
for inbound convos it is sent immediately when a new inbound conversation is made.
|
|
|
|
S bit 0 (LSB): we found the introset/endpoint for (set by outbound)
|
|
S bit 1: we found the router to align on (set by outbound)
|
|
S bit 2: we have a path right now (set by outbound)
|
|
S bit 3: we have made the converstation (set by both)
|
|
S bit 4: we are an inbound converstation (set by inbound)
|
|
|
|
{
|
|
A: "convo-status",
|
|
C: "<16 bytes session cookie>",
|
|
R: "human readable address .snode/.loki",
|
|
S: bitmask_status_uint64,
|
|
T: "<16 bytes convotag>",
|
|
Y: sequence_num_uint64,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
send or recieve authenticated data to or from the network (bidi)
|
|
|
|
protocol numbers are
|
|
|
|
1 for ipv4
|
|
2 for ipv6
|
|
|
|
{
|
|
A: "data",
|
|
C: "<16 bytes session cookie>",
|
|
T: "<16 bytes convotag>",
|
|
W: protocol_number_uint,
|
|
X: "<N bytes payload>",
|
|
Y: sequence_num_uint64,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
get session information (C->S)
|
|
|
|
{
|
|
A: "info",
|
|
C: "<16 bytes session cookie>",
|
|
Y: sequence_num_uint64,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
|
|
session information update (S->C)
|
|
|
|
sent in reply to a get session information message
|
|
|
|
{
|
|
A: "info-reply",
|
|
C: "<16 bytes session cookie>",
|
|
I: hiddenserviceinfo,
|
|
Y: sequence_num_uint64,
|
|
Z: "<32 bytes keyed hash>"
|
|
}
|
|
|
|
Protocol Flow:
|
|
|
|
all messages have an A, C, Y and Z value
|
|
|
|
A is the function name being called
|
|
|
|
C is the session cookie indicating the current session
|
|
|
|
Y is the 64 bit message sequence number as an integer
|
|
|
|
Z is the keyed hash computed by MDS(BE(msg), K) where K is HS(api_password)
|
|
with the msg.Z being set to 32 bytes of \x00
|
|
|
|
both client and server MUST know a variable length string api_password used to
|
|
authenticate access to the api subsystem.
|
|
|
|
the Y value is incremented by 1 for each direction every time the sender sends
|
|
a message in that direction.
|