Updated protocol docs for TCP forward support

This commit is contained in:
frekky 2016-02-07 21:59:27 +08:00
parent a5a936f4e4
commit c8105dcc08

View File

@ -42,19 +42,46 @@ Server replies:
Login:
Client sends:
First byte l or L
1 byte userid char (hex)
Rest encoded with base32:
1 byte userid
1 byte flags: (least to most significant bits)
0: connect to remote TCP port (data pipe/ProxyCommand mode)
1: use non-localhost remote IP
2: remote IP is IPv6
3: use TCP-over-tun optimisation (drop extra packets)
4: check forward connected status
5-8: unused
16 bytes MD5 hash of: (first 32 bytes of password) xor (8 repetitions of login challenge)
CMC
2 bytes remote TCP port (big endian)
(TCP port appears only when flags bit 0 is set)
4-16 bytes remote IP address (4 bytes if IPv4 or 16 for IPv6)
(IP address included only if flags bits 0, 1 are set)
2 bytes CMC
Server replies:
LNAK means not accepted
x.x.x.x-y.y.y.y-mtu-netmask means accepted (server ip, client ip, mtu, netmask bits)
LNAK means either auth or options not accepted
flag [-x.x.x.x-y.y.y.y-mtu-netmask]|[error message] means accepted
(server ip, client ip, mtu, netmask bits)
flag can be one of:
I: Login success (followed by IP addresses in [...])
C: TCP forward connected
W: TCP forward connection waiting
E: TCP connection error - followed by human readable message string
If the requested TCP forwarding options are not accepted by the server, the
response is simply LNAK.
If TCP forwarding is requested, server opens a connection to the specified host
and IP in the background and responds with a flag corresponding to the current
connection status.
The client repeats login requests with the check flag (bit 4) set to poll TCP
connection status, not resending the remote host address or setting any other
flags. Once the server responds with 'C' or 'E', the client either continues
the handshake or prints the error message and exits.
IP Request: (for where to try raw login or set data pipe mode)
IP Request: (for where to try raw login)
Client sends:
First byte i or I
5 bits coded as Base32 char, meaning userid
CMC as 3 Base32 chars
1 byte userid char (hex)
CMC as 4 Base32 chars
Server replies
BADIP if bad userid
First byte I
@ -73,8 +100,9 @@ Downstream codec check:
Client sends:
First byte y or Y
1 char, meaning downstream codec to use
5 bits coded as Base32 char, meaning check variant
CMC as 3 Base32 chars
rest encoded in base32:
1 byte check variant
2 bytes CMC
Possibly extra data, depending on check variant
Server sends:
Data encoded with requested downstream codec; data content depending
@ -93,59 +121,58 @@ Server sends:
Switch codec:
Client sends:
First byte s or S
5 bits coded as Base32 char, meaning userid
5 bits coded as Base32 char, representing number of raw bits per
encoded byte:
1 byte userid char (hex)
rest encoded in base32:
1 byte meaning number of bits per encoded byte in new codec:
5: Base32 (a-z0-5)
6: Base64 (a-zA-Z0-9+-)
26: Base64u (a-zA-Z0-9_-)
7: Base128 (a-zA-Z0-9\274-\375)
CMC as 3 Base32 chars
2 bytes CMC
Server sends:
Name of codec if accepted. After this all upstream data packets must
be encoded with the new codec.
BADCODEC if not accepted. Client must then revert to previous codec
BADLEN if length of query is too short
Options:
Set Options:
Client sends:
First byte o or O
5 bits coded as Base32 char, meaning userid
number of options (n) as decimal digit
n chars, each a valid option (to be processed in order)
CMC as 3 Base32 chars
1 byte userid char (hex)
rest encoded in base32:
1 byte option flags and 2 bytes CMC:
0 1 - 3
+76543210+---+
|0TSUVRCL|CMC|
+--------+---+
Server sends:
Option chars in the same order as request, indicating that options were
accepted by the server.
Full name of encoding type used if successful (case insensitive).
BADCODEC if not accepted. Previous situation remains.
BADLEN if number of options doesn't match length of query.
All options affect only the requesting client.
Option chars:
t or T: Downstream encoding Base32, for TXT/CNAME/A/MX (default)
s or S: Downstream encoding Base64, for TXT/CNAME/A/MX
u or U: Downstream encoding Base64u, for TXT/CNAME/A/MX
v or V: Downstream encoding Base128, for TXT/CNAME/A/MX
r or R: Downstream encoding Raw, for PRIVATE/TXT/NULL (assumed for
Option flags:
T: Downstream encoding Base32, for TXT/CNAME/A/MX (default)
S: Downstream encoding Base64, for TXT/CNAME/A/MX
U: Downstream encoding Base64u, for TXT/CNAME/A/MX
V: Downstream encoding Base128, for TXT/CNAME/A/MX
R: Downstream encoding Raw, for PRIVATE/TXT/NULL (assumed for
PRIVATE and NULL)
C: Downstream compression enabled (compressed before encoding)
L: Lazy mode enabled, server will keep a number of requests waiting until
data becomes available to send downstream or the requests time out.
The timeout value for requests is controlled by the client.
Applies only to data transfer; handshake is always answered immediately.
If codec unsupported for request type, server will use Base32; note
that server will answer any mix of request types that a client sends.
Server may disregard this option; client must always use the downstream
encoding type indicated in every downstream DNS packet.
Server may disregard the encoding options; client must always use the
downstream encoding type indicated in every downstream DNS packet.
c or C: Downstream compression enabled (compressed before encoding)
d or D: Downstream compression disabled
l or L: Lazy mode, server will keep a number of requests waiting until data
becomes available to send downstream or the requests time out. The
timeout value for requests is controlled by the client.
Applies only to data transfer; handshake is always answered immediately.
i or I: Immediate (non-lazy) mode, server will answer all requests
(nearly) immediately.
Probe downstream fragment size:
Client sends:
First byte r or R
Second byte userid char
1 byte userid char (hex)
2 bytes big-endian fragsize encoded as 4 bytes base32
Then follows a long random query which contents does not matter.
Server sends:
@ -158,8 +185,8 @@ Server sends:
Set downstream fragment size:
Client sends:
First byte n or N
1 byte userid char (hex)
Rest encoded with base32:
1 byte userid
2 bytes new downstream fragment size (big-endian)
CMC
Server sends:
@ -177,7 +204,7 @@ Upstream data header:
Downstream data header: |=> only if ping (P) flag set |
0 1 2 3 4 5 6
+--------+--------+76543210+--------+--------+--------+--------+
| Seq ID | Up ACK |00IPACFL|Dn Wsize|Up Wsize|DnWstart|UpWstart|
| Seq ID | Up ACK |0EIPACFL|Dn Wsize|Up Wsize|DnWstart|UpWstart|
+--------+--------+--------+--------+--------+--------+--------+
UUUU = Userid
@ -187,6 +214,7 @@ F = First fragment flag
C = Compression enabled for downstream packet
P = ping flag: extra header present
I = responded to immediately (for RTT calculation) - downstream only
E = TCP Forward error (data following is text string reason)
UDCMC = Upstream Data CMC char (base36 [a-z0-9])
Up/Dn Wsize/Wstart = upstream/downstream window size/window start Seq ID
@ -201,6 +229,9 @@ containing upstream and downstream window sizes and window start sequence IDs.
The response does not need to contain data. If the server has no data to send,
the response will always include the ping header and the ping flag will be set.
If the TCP forward error (E) flag is set, the TCP connection at the server is
closed and the client sends EOF to stdout and exits.
In NULL and PRIVATE responses, downstream data is always raw. In all other
response types, downstream data is encoded (see Options above).
Encoding type is indicated by 1 prefix char (before the data header):
@ -227,12 +258,12 @@ Ping:
Client sends:
First byte p or P
Second byte CMC
1 byte userid char (hex)
Rest encoded with Base32:
0 1 2...8 9-10
+--------+--------+---+76543210+---+
|0000UUUU|Dn SeqID|...|000WTANR|CMC|
+--------+--------+---+--------+---+
4 bits Userid
0 1...7 8 - 9
+--------+---+76543210+---+
|Dn SeqID|...|00DWTANR|CMC|
+--------+---+--------+---+
1 byte Downstream seq ID ACK
1 byte window size (upstream)
1 byte window size (downstream)
@ -242,6 +273,7 @@ Client sends:
2 bytes big-endian downstream fragment ACK timeout in ms
1 byte flags:
D = disconnect remote TCP forward (client should then exit)
W = update window frag timeout
T = update server timeout
A = is ACKing downstream frag
@ -257,6 +289,9 @@ The server must also adjust its window sizes to those provided by the ping.
If the T but is set, the server sets the user's DNS timeout to the value spec-
ified by the packet.
If the bit corresponding to changing a particular value (ie. window timeout) is
not set, the value should be random. (note: this is disabled in debug mode).
In lazy mode, unless the R flag is set, the server will hold the ping until it
times out or more data becomes available to send.
@ -299,8 +334,8 @@ pending queries) for ACKs or for new data.
======================================================
This protocol does not implement data windowing and does not guarantee data
delivery, however it is likely faster due to the fact that data is not split
into fragments for sending. Full packets are compressed and sent when they
delivery, however it is faster since the data is not encoded and transferred
on top of the DNS protocol. Full packets are compressed and sent when they
arrive on the tun device, and are processed immediately on the other side.
All Raw UDP protcol messages start with a 3 byte header: 0x10d19e