mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-03 23:15:52 +00:00
commit
3b006e67e8
215
docs/api_v0.txt
215
docs/api_v0.txt
@ -12,14 +12,23 @@ Overview:
|
||||
|
||||
LRTP is a message oriented data delivery and receival protocol for hidden
|
||||
service traffic. All structures are BitTorrent Encoded dictionaries sent
|
||||
over UDP.
|
||||
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: "<RouterID_0 + RouterID_1 + ... RouterID_N>" // 32 bytes aligned
|
||||
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>"
|
||||
}
|
||||
@ -30,161 +39,225 @@ Introduction: a hidden service introduction
|
||||
E: expiration_ms_since_epoch_uint64,
|
||||
L: advertised_latency_ms_uint64,
|
||||
P: "<16 bytes pathid>",
|
||||
R: "<32 bytes RouterID>",
|
||||
R: "<32 bytes RouterID>"
|
||||
}
|
||||
|
||||
ServiceInfo: public key blob for hidden service address
|
||||
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>",
|
||||
X: "computedbase32address.loki"
|
||||
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
|
||||
}
|
||||
|
||||
HiddenServiceMessage: a message sent between hidden services
|
||||
Converstation: information about a loki network converstation
|
||||
|
||||
{
|
||||
D: "<N bytes payload>",
|
||||
R: ServiceInfo of recipiant,
|
||||
S: ServiceInfo of source
|
||||
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>"
|
||||
}
|
||||
|
||||
HiddenServiceSessionInfo: information about our current session
|
||||
SessionInfo: information about our current session
|
||||
|
||||
{
|
||||
I: [inbound,convos,here],
|
||||
O: [outbound,covos,here],
|
||||
P: [Path0, Path1, .... PathN],
|
||||
I: "<32 byte aligned remote hidden services inbound>",
|
||||
O: "<32 byte aligned remote hidden services outbound>",
|
||||
S: Current ServiceInfo,
|
||||
S: Current IntroSet,
|
||||
}
|
||||
|
||||
Verbs (methods):
|
||||
|
||||
spawn a new hidden service (C->S)
|
||||
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",
|
||||
N: "Human Readable Name Of Hidden Service",
|
||||
Y: sequence_num_uint64,
|
||||
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",
|
||||
N: "Human Readable Name Of Hidden Service",
|
||||
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>"
|
||||
}
|
||||
|
||||
lookup an intro set for a remote hidden service (C->S)
|
||||
sent in reply to a make-convo message to indicate rejection (S->C)
|
||||
|
||||
{
|
||||
A: "lookup"
|
||||
N: "base32encoded.loki",
|
||||
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>"
|
||||
}
|
||||
|
||||
reply to a intro set lookup (S->C)
|
||||
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: "lookup",
|
||||
I: IntroSet,
|
||||
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>"
|
||||
Z: "<32 bytes keyed hash>
|
||||
}
|
||||
|
||||
infrom the status of a converstation on a loki address (S->C)
|
||||
|
||||
align a path to align with a remote endpoint by public router ID (C->S)
|
||||
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: "align",
|
||||
R: "<32 bytes router ID>",
|
||||
Y: sequence_num_uint64,
|
||||
Z: "<32 bytes keyed hash>"
|
||||
}
|
||||
|
||||
infrom that we have aligned with a remote endpoint (S->C)
|
||||
|
||||
{
|
||||
A: "align",
|
||||
R: "<32 bytes Router ID>",
|
||||
I: IntroForPathAligned,
|
||||
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",
|
||||
D: "destinationaddressbase32.loki",
|
||||
I: Introduction in use,
|
||||
S: "sourceaddressbase32.loki",
|
||||
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>"
|
||||
}
|
||||
|
||||
|
||||
sent in reply to every message indicating that it was recieved (bidi)
|
||||
get session information (C->S)
|
||||
|
||||
{
|
||||
A: "ack",
|
||||
A: "info",
|
||||
C: "<16 bytes session cookie>",
|
||||
Y: sequence_num_uint64,
|
||||
Z: "<32 bytes keyed hash>"
|
||||
}
|
||||
|
||||
send a session keep alive (bidi)
|
||||
|
||||
session information update (S->C)
|
||||
|
||||
sent in reply to a get session information message
|
||||
|
||||
{
|
||||
A: "keepalive",
|
||||
Y: sequence_num_uint64,
|
||||
Z: "<32 bytes keyed hash>",
|
||||
}
|
||||
|
||||
exit session (bidi)
|
||||
|
||||
{
|
||||
A: "exit",
|
||||
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, Y and Z value
|
||||
all messages have an A, C, Y and Z value
|
||||
|
||||
A is the function name being called
|
||||
|
||||
Y is the 64 bit message sequence number
|
||||
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.
|
||||
|
||||
first message MUST be a spawn message, before any other messages are sent by
|
||||
client (other than keepalives and acl) the client MUST wait for the server to
|
||||
send a spawn message in reply.
|
||||
|
||||
once the server spawn message is sent lookup messages may be sent.
|
||||
|
||||
when a lookup is done by the client, the router looks up the descriptor from
|
||||
the DHT. when a response is obtained the api server gives the introset to
|
||||
the client.
|
||||
|
||||
in order to send data to a remote hidden service, the client must align a path
|
||||
to a intro in the hidden service's intro set.
|
||||
|
||||
after alignment is done, data messages may flow in a bidirectional manner.
|
||||
the Y value is incremented by 1 for each direction every time the sender sends
|
||||
a message in that direction.
|
||||
|
Loading…
Reference in New Issue
Block a user