Skip to content

Commit d7c681d

Browse files
committed
Add Max Payload Size limit option (--max-payload-size)
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.
1 parent ab74ddc commit d7c681d

File tree

2 files changed

+47
-10
lines changed

2 files changed

+47
-10
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ Usage: goodbyedpi.exe [OPTION...]
5858
--reverse-frag fragment (split) the packets just as --native-frag, but send them in the
5959
reversed order. Works with the websites which could not handle segmented
6060
HTTPS TLS ClientHello (because they receive the TCP flow "combined").
61+
--max-payload [value] packets with TCP payload data more than [value] won't be processed.
62+
Use this option to reduce CPU usage by skipping huge amount of data
63+
(like file transfers) in already established sessions.
64+
May skip some huge HTTP requests from being processed.
6165
6266
6367
LEGACY modesets:

src/goodbyedpi.c

+43-10
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ WINSOCK_API_LINKAGE INT WSAAPI inet_pton(INT Family, LPCSTR pStringBuf, PVOID pA
6161

6262
/* #IPID# is a template to find&replace */
6363
#define IPID_TEMPLATE "#IPID#"
64+
#define MAXPAYLOADSIZE_TEMPLATE "#MAXPAYLOADSIZE#"
6465
#define FILTER_STRING_TEMPLATE \
65-
"(tcp and !impostor and !loopback and " \
66+
"(tcp and !impostor and !loopback " MAXPAYLOADSIZE_TEMPLATE " and " \
6667
"((inbound and (" \
6768
"(" \
6869
"(" \
@@ -169,6 +170,7 @@ static struct option long_options[] = {
169170
{"wrong-seq", no_argument, 0, ')' },
170171
{"native-frag", no_argument, 0, '*' },
171172
{"reverse-frag",no_argument, 0, '(' },
173+
{"max-payload", optional_argument, 0, '|' },
172174
{0, 0, 0, 0 }
173175
};
174176

@@ -178,7 +180,7 @@ static char *filter_passive_string = NULL;
178180
static void add_filter_str(int proto, int port) {
179181
const char *udp = " or (udp and !impostor and !loopback and " \
180182
"(udp.SrcPort == %d or udp.DstPort == %d))";
181-
const char *tcp = " or (tcp and !impostor and !loopback and " \
183+
const char *tcp = " or (tcp and !impostor and !loopback " MAXPAYLOADSIZE_TEMPLATE " and " \
182184
"(tcp.SrcPort == %d or tcp.DstPort == %d))";
183185

184186
char *current_filter = filter_string;
@@ -212,11 +214,25 @@ static void add_ip_id_str(int id) {
212214
filter_passive_string = newstr;
213215
}
214216

215-
static void finalize_filter_strings() {
217+
static void add_maxpayloadsize_str(unsigned short maxpayload) {
216218
char *newstr;
219+
const char *maxpayloadsize_str = "and (tcp.PayloadLength ? tcp.PayloadLength < %hu : true)";
220+
char *addfilter = malloc(strlen(maxpayloadsize_str) + 16);
221+
222+
sprintf(addfilter, maxpayloadsize_str, maxpayload);
223+
224+
newstr = repl_str(filter_string, MAXPAYLOADSIZE_TEMPLATE, addfilter);
225+
free(filter_string);
226+
filter_string = newstr;
227+
}
228+
229+
static void finalize_filter_strings() {
230+
char *newstr, *newstr2;
217231

218-
newstr = repl_str(filter_string, IPID_TEMPLATE, "");
232+
newstr2 = repl_str(filter_string, IPID_TEMPLATE, "");
233+
newstr = repl_str(newstr2, MAXPAYLOADSIZE_TEMPLATE, "");
219234
free(filter_string);
235+
free(newstr2);
220236
filter_string = newstr;
221237

222238
newstr = repl_str(filter_passive_string, IPID_TEMPLATE, "");
@@ -558,6 +574,7 @@ int main(int argc, char *argv[]) {
558574
unsigned int http_fragment_size = 0;
559575
unsigned int https_fragment_size = 0;
560576
unsigned int current_fragment_size = 0;
577+
unsigned short max_payload_size = 0;
561578
BYTE should_send_fake = 0;
562579
BYTE ttl_of_fake_packet = 0;
563580
BYTE ttl_min_nhops = 0;
@@ -845,6 +862,14 @@ int main(int argc, char *argv[]) {
845862
do_fragment_http_persistent = 1;
846863
do_fragment_http_persistent_nowait = 1;
847864
break;
865+
case '|': // --max-payload
866+
if (!optarg && argv[optind] && argv[optind][0] != '-')
867+
optarg = argv[optind];
868+
if (optarg)
869+
max_payload_size = atousi(optarg, "Max payload size parameter error!");
870+
if (!max_payload_size)
871+
max_payload_size = 1200;
872+
break;
848873
default:
849874
puts("Usage: goodbyedpi.exe [OPTION...]\n"
850875
" -p block passive DPI\n"
@@ -888,9 +913,13 @@ int main(int argc, char *argv[]) {
888913
" --reverse-frag fragment (split) the packets just as --native-frag, but send them in the\n"
889914
" reversed order. Works with the websites which could not handle segmented\n"
890915
" HTTPS TLS ClientHello (because they receive the TCP flow \"combined\").\n"
891-
"\n"
892-
"\n"
893-
"LEGACY modesets:\n"
916+
" --max-payload [value] packets with TCP payload data more than [value] won't be processed.\n"
917+
" Use this option to reduce CPU usage by skipping huge amount of data\n"
918+
" (like file transfers) in already established sessions.\n"
919+
" May skip some huge HTTP requests from being processed.\n"
920+
" Default (if set): --max-payload 1200.\n"
921+
"\n");
922+
puts("LEGACY modesets:\n"
894923
" -1 -p -r -s -f 2 -k 2 -n -e 2 (most compatible mode)\n"
895924
" -2 -p -r -s -f 2 -k 2 -n -e 40 (better speed for HTTPS yet still compatible)\n"
896925
" -3 -p -r -s -e 40 (better speed for HTTP and HTTPS)\n"
@@ -935,7 +964,8 @@ int main(int argc, char *argv[]) {
935964
"Allow missing SNI: %d\n" /* 15 */
936965
"Fake requests, TTL: %s (fixed: %hu, auto: %hu-%hu-%hu, min distance: %hu)\n" /* 16 */
937966
"Fake requests, wrong checksum: %d\n" /* 17 */
938-
"Fake requests, wrong SEQ/ACK: %d\n", /* 18 */
967+
"Fake requests, wrong SEQ/ACK: %d\n" /* 18 */
968+
"Max payload size: %hu\n", /* 19 */
939969
do_passivedpi, /* 1 */
940970
(do_fragment_http ? http_fragment_size : 0), /* 2 */
941971
(do_fragment_http_persistent ? http_fragment_size : 0),/* 3 */
@@ -955,7 +985,8 @@ int main(int argc, char *argv[]) {
955985
ttl_of_fake_packet, do_auto_ttl ? auto_ttl_1 : 0, do_auto_ttl ? auto_ttl_2 : 0,
956986
do_auto_ttl ? auto_ttl_max : 0, ttl_min_nhops,
957987
do_wrong_chksum, /* 17 */
958-
do_wrong_seq /* 18 */
988+
do_wrong_seq, /* 18 */
989+
max_payload_size /* 19 */
959990
);
960991

961992
if (do_fragment_http && http_fragment_size > 2 && !do_native_frag) {
@@ -970,8 +1001,10 @@ int main(int argc, char *argv[]) {
9701001
exit(EXIT_FAILURE);
9711002
}
9721003

973-
puts("\nOpening filter");
1004+
if (max_payload_size)
1005+
add_maxpayloadsize_str(max_payload_size);
9741006
finalize_filter_strings();
1007+
puts("\nOpening filter");
9751008
filter_num = 0;
9761009

9771010
if (do_passivedpi) {

0 commit comments

Comments
 (0)