From 0280fe383f96f06f4e14e9e37fbe895ae1787f92 Mon Sep 17 00:00:00 2001 From: Vadim Vetrov Date: Fri, 3 Jan 2025 15:52:53 +0300 Subject: [PATCH] Add --udp-filter-quic=parse This will enable QUIC decryption and parsing. --- README.md | 16 ++++++++++++---- src/args.c | 7 ++++++- src/config.h | 1 + src/quic.c | 10 ++++++++-- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 380dd32..72faf4d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ - [IPv6](#ipv6) - [Check it](#check-it) - [Flags](#flags) - - [UDP](#udp) + - [UDP/QUIC](#udp/quic) - [Troubleshooting](#troubleshooting) - [TV](#tv) - [Troubleshooting EPERMS (Operation not permitted)](#troubleshooting-eperms-operation-not-permitted) @@ -270,13 +270,21 @@ Flags that do not scoped to a specific section, used over all the youtubeUnblock - `--udp-faking-strategy={checksum|ttl|none}` Faking strategy for udp. `checksum` will fake UDP checksum, `ttl` won't fake but will make UDP content relatively small, `none` is no faking. Defaults to none. -- `--udp-filter-quic={disabled|all}` Enables QUIC filtering for UDP handler. If disabled, quic won't be processed, if all, all quic initial packets will be handled. Defaults to disabled. +- `--udp-filter-quic={disabled|all|parsed}` Enables QUIC filtering for UDP handler. If disabled, quic won't be processed, if all, all quic initial packets will be handled. `parsed` will decrypt and parse QUIC initial message and match it with `--sni-domains`. Defaults to disabled. - `--quic-drop` Drop all QUIC packets which goes to youtubeUnblock. Won't affect any other UDP packets. Just an alias for `--udp-filter-quic=all --udp-mode=drop`. -## UDP +## UDP/QUIC -UDP is another communication protocol. Well-known technologies that use it are DNS, QUIC, voice chats. UDP does not provide reliable connection and its header is much simpler than TCP thus fragmentation is limited. The support provided primarily by faking. For QUIC faking may not work well, so use `--quic-drop` if you want to drop all quic traffic. For other technologies I recommend to configure UDP support in the separate section from TCP, like `--fbegin --udp-dport-filter=50000-50099 --tls=disabled`. See more in flags related to udp and [issues tagged with udp label](https://github.com/Waujito/youtubeUnblock/issues?q=label%3Audp+). +UDP is another communication protocol. Well-known technologies that use it are DNS, QUIC, voice chats. UDP does not provide reliable connection and its header is much simpler than TCP thus fragmentation is limited. The support provided primarily by faking. + +Right now, QUIC faking may not work well, so use `--udp-mode=drop` option. + +QUIC is enabled with `--udp-filter-quic` flag. The flag supports two modes: `all` will handle all the QUIC initial messages and `parse` will decrypt and parse the QUIC initial message, and then compare it with `--sni-domains` flag. + +**I recommend to use** `--udp-mode=drop --udp-filter-quic=parse`. + +For **other UDP protocols** I recommend to configure UDP support in the separate section from TCP, like `--fbegin --udp-dport-filter=50000-50099 --tls=disabled`. See more in flags related to udp and [tickets tagged with udp label](https://github.com/Waujito/youtubeUnblock/issues?q=label%3Audp+). ## Troubleshooting diff --git a/src/args.c b/src/args.c index dd2f0fa..e0730d0 100644 --- a/src/args.c +++ b/src/args.c @@ -368,7 +368,7 @@ void print_usage(const char *argv0) { printf("\t--udp-fake-len=\n"); printf("\t--udp-faking-strategy={checksum|ttl|none}\n"); printf("\t--udp-dport-filter=<5,6,200-500>\n"); - printf("\t--udp-filter-quic={disabled|all}\n"); + printf("\t--udp-filter-quic={disabled|all|parsed}\n"); printf("\t--threads=\n"); printf("\t--packet-mark=\n"); printf("\t--connbytes-limit=\n"); @@ -764,6 +764,8 @@ int yparse_args(int argc, char *argv[]) { sect_config->udp_filter_quic = UDP_FILTER_QUIC_DISABLED; } else if (strcmp(optarg, "all") == 0) { sect_config->udp_filter_quic = UDP_FILTER_QUIC_ALL; + } else if (strcmp(optarg, "parsed") == 0) { + sect_config->udp_filter_quic = UDP_FILTER_QUIC_PARSED; } else { goto invalid_opt; } @@ -930,6 +932,9 @@ static size_t print_config_section(const struct section_config_t *section, char case UDP_FILTER_QUIC_DISABLED: print_cnf_buf("--udp-filter-quic=disabled"); break; + case UDP_FILTER_QUIC_PARSED: + print_cnf_buf("--udp-filter-quic=parsed"); + break; } if (section->udp_dport_range_len != 0) { diff --git a/src/config.h b/src/config.h index 59796ad..f11aef6 100644 --- a/src/config.h +++ b/src/config.h @@ -218,6 +218,7 @@ enum { enum { UDP_FILTER_QUIC_DISABLED, UDP_FILTER_QUIC_ALL, + UDP_FILTER_QUIC_PARSED, }; #define default_section_config { \ diff --git a/src/quic.c b/src/quic.c index 4ebaf4d..288d354 100644 --- a/src/quic.c +++ b/src/quic.c @@ -404,7 +404,7 @@ int detect_udp_filtered(const struct section_config_t *section, goto skip; } - if (section->udp_filter_quic) { + if (section->udp_filter_quic != UDP_FILTER_QUIC_DISABLED) { const struct quic_lhdr *qch; uint32_t qch_len; struct quic_cids qci; @@ -430,6 +430,12 @@ int detect_udp_filtered(const struct section_config_t *section, goto match_port; } + if (section->udp_filter_quic == UDP_FILTER_QUIC_ALL || + section->all_domains) { + lgtrace_addp("QUIC early approve"); + goto approve; + } + uint8_t *decrypted_payload; uint32_t decrypted_payload_len; const uint8_t *decrypted_message; @@ -452,7 +458,7 @@ int detect_udp_filtered(const struct section_config_t *section, ); if (tlsv.sni_len != 0) { - lgdebugmsg("QUIC SNI detected: %.*s", tlsv.sni_len, tlsv.sni_ptr); + lgtrace_addp("QUIC SNI detected: %.*s", tlsv.sni_len, tlsv.sni_ptr); } if (tlsv.target_sni) {