syntax = "proto3"; package ya_relay_proto; /* 1. Requests and responses are tied to a common ID. 2. Connection initialization messages are sent in a sequence, 3. Control messages must not be responded to, 4. Response::Node sent to Request::Node contains a corresponding `node_id`, 5. Request::Node with empty node_id requests information on a random node. */ /* P2P Client A <- [ Request :: Session (Ei|Rq) ] -- Client B Client A -- [ Response :: Session (Rq) ] -> Client B Client A <- [ Request :: Session (Rs) ] -- Client B Client A -- [ Response :: Session (Rs) ] -> Client B (Ei): empty session id (Rq): challenge request (Rs): challenge response Central Server Server <- [ Request :: Session (Ei) ] -- Client A Server -- [ Response :: Session (Rq) ] -> Client A Server <- [ Request :: Session (Rs) ] -- Client A Server -- [ Response :: Session ] -> Client A (Ei): empty session id (Rq): challenge request (Rs): challenge response */ /* message Forward {} // (tag = 1) */ message Packet { bytes session_id = 2; // empty for `Request::Session` oneof kind { Request request = 3; Response response = 4; Control control = 5; } } /* Forward request to client B sent by client A to the server or a forwarded message sent by the server to client B. `Forward` serves only as a message type marker (i.e. equal to 1). The message is of custom binary format, similar to: message Forward { bytes session_id = 1; uint32 slot = 2; // either sender or receiver slot id uint16 flags = 3; bytes payload = 4; } */ /* Challenge newly-connected nodes */ message ChallengeRequest { enum Kind { UNDEFINED = 0; SHA3_512_LEADING_ZEROS = 10; } string version = 1; /* Capabilities bit field */ uint64 caps = 2; Kind kind = 3; uint64 difficulty = 4; bytes challenge = 5; } /* Response to session challenge */ message ChallengeResponse { bytes solution = 1; /* First signature by default identity */ repeated bytes signatures = 2; } /* Requests sent to the server by the client */ message Request { uint64 request_id = 1; oneof kind { Session session = 10; Register register = 20; Node node = 30; Slot slot = 31; Neighbours neighbours = 40; ReverseConnection reverse_connection = 50; Ping ping = 80; } // Session initialization. message Session { // Empty if optional ChallengeRequest challenge_req = 1; optional ChallengeResponse challenge_resp = 2; // Supported encryption schemes, in order of preference repeated string supported_encryptions = 3; /* First identity is the default one. For non-default encryption schemes. */ repeated Identity identities = 4; } message Register { /* Listening endpoints */ repeated Endpoint endpoints = 1; } message Node { /* Remote node ID */ bytes node_id = 1; /* Whether to include public key */ bool public_key = 2; } message Slot { /* Node slot ID */ uint32 slot = 1; /* Whether to include public key */ bool public_key = 2; } message Neighbours { uint32 count = 1; /* Whether to include public keys */ bool public_key = 2; } message ReverseConnection { /* Remote node ID */ bytes node_id = 1; } message Ping {} } /* Responses sent by the server to the client */ message Response { uint64 request_id = 1; StatusCode code = 2; oneof kind { Session session = 11; Register register = 20; Node node = 30; Neighbours neighbours = 40; ReverseConnection reverse_connection = 60; Pong pong = 80; } /* Session ACK */ message Session { ChallengeRequest challenge_req = 1; ChallengeResponse challenge_resp = 2; /* Supported encryption schemes, in order of preference */ repeated string supported_encryptions = 3; /* First identity is the default one. For non-default encryption schemes. */ repeated Identity identities = 4; } /* Registered endpoints */ message Register { /* Discovered endpoints */ repeated Endpoint endpoints = 1; } /* Node information */ message Node { repeated Identity identities = 1; repeated Endpoint endpoints = 2; uint64 seen_ts = 3; uint32 slot = 4; repeated string supported_encryptions = 5; } /* Neighbourhood */ message Neighbours { repeated Node nodes = 1; } message ReverseConnection {} message Pong {} } /* Control messages (w/o response) sent by server to the client */ message Control { oneof kind { ReverseConnection reverse_connection = 10; PauseForwarding pause_forwarding = 20; ResumeForwarding resume_forwarding = 21; StopForwarding stop_forwarding = 22; Disconnected disconnected = 23; } /* Connect to another node */ message ReverseConnection { bytes node_id = 1; repeated Endpoint endpoints = 2; } message PauseForwarding { uint32 slot = 1; } message ResumeForwarding { uint32 slot = 1; } message StopForwarding { uint32 slot = 1; StatusCode code = 3; } /* Node disconnected. Receiver of this message should stop forwarding */ message Disconnected { oneof by { uint32 slot = 1; bytes node_id = 2; bytes session_id = 3; } } } enum StatusCode { UNDEFINED = 0; OK = 200; BAD_REQUEST = 400; UNAUTHORIZED = 401; NOT_FOUND = 404; TIMEOUT = 408; CONFLICT = 409; PAYLOAD_TOO_LARGE = 413; TOO_MANY_REQUESTS = 429; SERVER_ERROR = 500; GATEWAY_TIMEOUT = 504; } enum Protocol { UNSUPPORTED = 0; TCP = 6; UDP = 17; } message Identity { bytes public_key = 1; bytes node_id = 2; } message Endpoint { Protocol protocol = 1; string address = 2; uint32 port = 3; }