Juicity Protocol Specification
The design philosophy of Juicity is to be simple yet effective in utilizing QUIC.
Conventions
The key terms "MUST", "SHOULD" and "SHOULD NOT" in this protocol specification are to be interpreted as described in RFC2119.
The term "connection" in the protocol specification generally refers to QUIC connection. In Juicity, TCP connections are carried over streams of QUIC connections, thus:
QUIC connection : QUIC stream : TCP connection
= 1 : N : N
Transport Layer
Juicity uses QUIC as its transport layer, which ensures information security, multiplexing, reliability, and high bandwidth.
Juicity requires that QUIC MUST support the BBR congestion control algorithm at a minimum. It also requires that the version of TLS MUST be 1.3 or above, and ALPN MUST be h3.
It's important to note that under normal circumstances, QUIC may impose limits on maxOpenIncomingStreams. The client MUST maintain a dynamic count of available streams on the remote QUIC connection. When the available count is insufficient, new connections MUST be established to handle incoming stream open requests.
Protocol Design
Authenticate
Juicity performs user authentication using UUID and password. A single QUIC connection can carry multiple QUIC streams, and for each QUIC connection, authentication is required only once.
The client opens a unidirectional stream to send an authentication request to the server.
enum bit<8> CmdType {
Authentication = 0;
};
header auth_h {
bit<128> uuid;
bit<256> token;
}
header_union command_body {
auth_h auth;
};
header command_t {
bit<8> version;
CmdType cmd_type;
};
The token is generated using TLS Keying Material Export (RFC 5705).
Proxy
Header
The specific format of the proxy header is as follows:
enum bit<8> Network {
TCP = 1,
UDP = 3
};
enum bit<8> AddrType {
IPV4 = 0,
IPV6 = 1,
DOMAIN = 2
};
header domain_address_t {
bit<8> len;
varbit<2048> domain;
};
// address_t can be one of ipv4, ipv6 and domain.
header_union address_t {
bit<32> ipv4;
bit<128> ipv6;
domain_address_t domain;
};
header proxy_t {
Network network;
AddrType addr_type;
address_t address;
bit<16> port;
};
TCP
For each TCP connection proxy request, the client opens a stream and sends the proxy header and payload.
UDP
Juicity's UDP datagrams are transmitted over QUIC streams. To achieve better full-cone NAT support, the datagrams of each source address triplet (<source IP, source port, UDP>) SHOULD be transmitted over the same stream.
Format for UDP packets over stream:
[proxy header][length][payload]