This option excludes TCP packets with the data payload larger than
defined value from being copied by WinDivert driver to GoodbyeDPI.
As most of HTTP and TLS ClientHello packets are repatively small,
and file transfers are usually big and are sent/received using
the whole available MTU/MSS, we can just exclude them from
being processed by our userspace program to reduce unnecessary
CPU load.
This option is added specially for protonmail.com, as it sends
low Window Size in SYN-ACK for requests from Russia, to force
the client to fragment the packet. GoodbyeDPI doesn't do reassembling
and can't extract SNI in this case, thus won't circumvent the
censorship if --blacklist option is used.
This patchset adds maximum TTL size of the fake packet to be sent,
to further improve compatibility with asymmertic routing and
non-standard TTL value set on servers.
Say you set --auto-ttl to 4.
If the TTL distance to the destination host is too short, say 6, auto-ttl
would decrease it by 4 and send a fake packet with TTL 2, which is too low
for the packet to travel via DPI system.
But if you set --auto-ttl to a lower value such as 2, that may introduce
issues over long lines where outgoing-path TTL and incoming-path TTL may have
difference more than 2 hops due to higher chance of assymetric routing along
the path.
To solve this issue, this commit introduce auto-ttl range of two values.
If the incoming TTL distance is more than autottl2, it is subtracted by
autottl2 value.
If the distance is less than autottl2, the distance value is used as a
normalized weigth of [autottl1; autottl2] scale.
The simplified formula is as follows:
128 > extracted_ttl > 98: // Server is running Windows
nhops = 128 - extracted_ttl
64 > extracted_ttl > 34: // Server is running Linux/FreeBSD/other
nhops = 64 - extracted_ttl
if (nhops - autottl2 < autottl2)
ttl_of_fake_packet = nhops - autottl1 - trunc((autottl2 - autottl1) * ((float)nhops/10));
else
ttl_of_fake_packet = nhops - autottl2
This is a per-connection (per-destination) automatic TTL adjusting feature.
Basically a --set-ttl mode where you don't need to set specific TTL value.
It works as follows:
1. All incoming SYN/ACKs (the response to client's SYN) are intercepted
2. TTL value is extracted from SYN/ACK
3. New TTL is calculated with the simple formula:
128 > extracted_ttl > 64: // Server is running Windows
fakepacket_ttl = 128 - extracted_ttl - decrement
64 > extracted_ttl > 34: // Server is running Linux/FreeBSD/other
fakepacket_ttl = 64 - extracted_ttl - decrement
4. Fake packet is sent
To comply with the multi-path multi-hop server connections
where 1 hop dispersion is not rare, decrement should be at least of
value "2", which is the default.
The patch does not process "too strange" TTL values (bigger than 128,
less than 34).
This method sends Fake Packet with the TCP SEQ/ACK numbers "in the past":
-66000 is used for ACK (right out of the ACK permissive window in Linux stack),
-10000 is used for SEQ (without any reasoning).
This method is pretty effective in Russia.
It also could be handy in a networks which prohibit changing TTL values
(mobile networks with tethering block/premium feature).
Before: --set-ttl and --wrong-chksum generated single Fake Packet with both low TTL and incorrect checksum.
Now: --set-ttl and --wrong-chksum generate two packets: one with low TTL, another with incorrect checksum.
Some websites (or more precisely, TLS terminators/balancers) can't
handle segmented TLS ClientHello packet properly, requiring the whole
ClientHello in a single segment, otherwise the connection gets dropped.
However they still operate with a proper TCP stack.
Cheat on them: send the latter segment first (with TCP SEQ "in the future"),
the former segment second (with "current" SEQ), allowing OS TCP
stack to combine it in a single TCP read().
This fixes long-standing number of TCP fragmentation issues:
Fixes#4, #158, #224, #59, #192 and many others.
This patch adds `--native-frag` option for userspace TCP
segmentation (packet splitting), without shrinking
TCP Window Size in SYN/ACK.
Compared to Window Size shrinking, this method does not require
waiting for ACK, which saves two RTTs.
This is preferrable method of operation since it has no cons.
It's faster and easier to handle in the software.