From 254b36359953c8cee61982543cf2ace8e7745273 Mon Sep 17 00:00:00 2001 From: Vadim Vetrov Date: Sun, 29 Dec 2024 23:01:26 +0300 Subject: [PATCH] Add none strategy to udp-faking-strategy --- Makefile | 2 +- README.md | 2 ++ args.c | 9 ++++++++- config.h | 3 ++- mangle.c | 1 + quic.c | 5 +++-- utils.c | 41 +++++++++++++++++++++++++++++++++++++++++ utils.h | 3 +++ 8 files changed, 61 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 01205e8..c2a7b2d 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ USPACE_TARGETS := default all install uninstall dev run_dev KMAKE_TARGETS := kmake kload kunload kreload xmod xtclean PKG_VERSION := 1.0.0 -PKG_RELEASE := 5 +PKG_RELEASE := 6 PKG_FULLVERSION := $(PKG_VERSION)-$(PKG_RELEASE) diff --git a/README.md b/README.md index fd462ea..380dd32 100644 --- a/README.md +++ b/README.md @@ -268,6 +268,8 @@ Flags that do not scoped to a specific section, used over all the youtubeUnblock - `--udp-dport-filter=<5,6,200-500>` Filter the UDP destination ports. Defaults to no ports. Specifie the ports you want to be handled by 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. - `--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`. diff --git a/args.c b/args.c index 3656916..b0cae9e 100644 --- a/args.c +++ b/args.c @@ -347,7 +347,7 @@ void print_usage(const char *argv0) { printf("\t--udp-mode={drop|fake}\n"); printf("\t--udp-fake-seq-len=\n"); printf("\t--udp-fake-len=\n"); - printf("\t--udp-faking-strategy={checksum|ttl}\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--threads=\n"); @@ -709,6 +709,8 @@ int yparse_args(int argc, char *argv[]) { sect_config->udp_faking_strategy = FAKE_STRAT_UDP_CHECK; } else if (strcmp(optarg, "ttl") == 0) { sect_config->udp_faking_strategy = FAKE_STRAT_TTL; + } else if (strcmp(optarg, "none") == 0) { + sect_config->udp_faking_strategy = FAKE_STRAT_NONE; } else { goto invalid_opt; } @@ -938,6 +940,11 @@ static size_t print_config_section(const struct section_config_t *section, char break; case FAKE_STRAT_TTL: print_cnf_buf("--udp-faking-strategy=ttl"); + print_cnf_buf("--faking-ttl=%d", section->faking_ttl); + break; + case 0: + print_cnf_buf("--udp-faking-strategy=none"); + break; } } break; diff --git a/config.h b/config.h index 5a1cd7a..b0ba183 100644 --- a/config.h +++ b/config.h @@ -148,6 +148,7 @@ for (struct section_config_t *section = (config)->last_section; section != NULL; #define FAKE_TTL 8 +#define FAKE_STRAT_NONE 0 // Will invalidate fake packets by out-of-ack_seq out-of-seq request #define FAKE_STRAT_RAND_SEQ (1 << 0) // Will assume that GGC server is located further than FAKE_TTL @@ -228,7 +229,7 @@ enum { .udp_mode = UDP_MODE_FAKE, \ .udp_fake_seq_len = 6, \ .udp_fake_len = 64, \ - .udp_faking_strategy = FAKE_STRAT_UDP_CHECK, \ + .udp_faking_strategy = FAKE_STRAT_NONE, \ .udp_dport_range = NULL, \ .udp_dport_range_len = 0, \ .udp_filter_quic = UDP_FILTER_QUIC_DISABLED, \ diff --git a/mangle.c b/mangle.c index d474f88..3cf210b 100644 --- a/mangle.c +++ b/mangle.c @@ -383,6 +383,7 @@ int process_udp_packet(const struct section_config_t *section, const uint8_t *pk .fake_len = section->udp_fake_len, .strategy = { .strategy = section->udp_faking_strategy, + .faking_ttl = section->faking_ttl, }, }; ret = gen_fake_udp(fake_type, iph, iph_len, udph, fake_udp, &fsn_len); diff --git a/quic.c b/quic.c index 24a8efc..339616b 100644 --- a/quic.c +++ b/quic.c @@ -159,7 +159,7 @@ int udp_fail_packet(struct udp_failing_strategy strategy, uint8_t *payload, uint if (strategy.strategy == FAKE_STRAT_TTL) { - lgtrace_addp("set fake ttl to %d", strategy.faking_ttl); + lgtrace_addp("Set fake ttl to %d", strategy.faking_ttl); if (ipxv == IP4VERSION) { ((struct iphdr *)iph)->ttl = strategy.faking_ttl; @@ -237,7 +237,8 @@ int gen_fake_udp(struct udp_fake_type type, struct udphdr *nudph = (struct udphdr *)(buf + iph_len); nudph->len = htons(sizeof(struct udphdr) + data_len); - + + set_udp_checksum(nudph, buf, iph_len); udp_fail_packet(type.strategy, buf, &dlen, *buflen); diff --git a/utils.c b/utils.c index bfaf0ba..ecb6af5 100644 --- a/utils.c +++ b/utils.c @@ -7,6 +7,7 @@ #include #include #include +#include #else #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) #include @@ -31,6 +32,20 @@ void tcp4_set_checksum(struct tcphdr *tcph, struct iphdr *iph) #endif } +void udp4_set_checksum(struct udphdr *udph, struct iphdr *iph) +{ +#ifdef KERNEL_SPACE + uint32_t udp_packet_len = ntohs(iph->tot_len) - (iph->ihl << 2); + udph->check = 0; + udph->check = csum_tcpudp_magic( + iph->saddr, iph->daddr, udp_packet_len, + IPPROTO_UDP, + csum_partial(udph, udp_packet_len, 0)); +#else + nfq_udp_compute_checksum_ipv4(udph, iph); +#endif +} + void ip4_set_checksum(struct iphdr *iph) { #ifdef KERNEL_SPACE @@ -52,6 +67,17 @@ void tcp6_set_checksum(struct tcphdr *tcph, struct ip6_hdr *iph) { #endif } +void udp6_set_checksum(struct udphdr *udph, struct ip6_hdr *iph) { +#ifdef KERNEL_SPACE + udph->check = 0; + udph->check = csum_ipv6_magic(&iph->saddr, &iph->daddr, + ntohs(iph->ip6_plen), IPPROTO_UDP, + csum_partial(udph, ntohs(iph->ip6_plen), 0)); +#else + nfq_udp_compute_checksum_ipv6(udph, iph); +#endif +} + int set_ip_checksum(void *iph, uint32_t iphb_len) { int ipvx = netproto_version(iph, iphb_len); @@ -77,6 +103,21 @@ int set_tcp_checksum(struct tcphdr *tcph, void *iph, uint32_t iphb_len) { return 0; } +int set_udp_checksum(struct udphdr *udph, void *iph, uint32_t iphb_len) { + int ipvx = netproto_version(iph, iphb_len); + + if (ipvx == IP4VERSION) { + udp4_set_checksum(udph, iph); + } else if (ipvx == IP6VERSION) { + udp6_set_checksum(udph, iph); + } else { + return -1; + } + + return 0; +} + + int ip4_payload_split(uint8_t *pkt, uint32_t buflen, struct iphdr **iph, uint32_t *iph_len, uint8_t **payload, uint32_t *plen) { diff --git a/utils.h b/utils.h index 7a5a629..439dbcd 100644 --- a/utils.h +++ b/utils.h @@ -96,9 +96,12 @@ void tcp4_set_checksum(struct tcphdr *tcph, struct iphdr *iph); void ip4_set_checksum(struct iphdr *iph); void ip6_set_checksum(struct ip6_hdr *iph); void tcp6_set_checksum(struct tcphdr *tcph, struct ip6_hdr *iph); +void udp4_set_checksum(struct udphdr *udph, struct iphdr *iph); +void udp6_set_checksum(struct udphdr *udph, struct ip6_hdr *iph); int set_ip_checksum(void *iph, uint32_t iphb_len); int set_tcp_checksum(struct tcphdr *tcph, void *iph, uint32_t iphb_len); +int set_udp_checksum(struct udphdr *udph, void *iph, uint32_t iphb_len); void z_function(const char *str, int *zbuf, size_t len);