From 4c7b63fa7f0f9bfdb01c0034dc8908b21034f92e Mon Sep 17 00:00:00 2001 From: Vadim Vetrov Date: Sun, 13 Oct 2024 23:31:26 +0300 Subject: [PATCH] Add multiple sections with config sets for various domains --- README.md | 2 + args.c | 407 ++++++++++++++++++++++++++--------------------- config.h | 54 +++++-- kargs.c | 113 +++++++------ kytunblock.c | 21 +-- mangle.c | 161 ++++++++++--------- mangle.h | 10 +- tls.c | 45 +++--- tls.h | 2 +- utils.h | 24 +-- youtubeUnblock.c | 24 +-- 11 files changed, 450 insertions(+), 413 deletions(-) diff --git a/README.md b/README.md index bae083a..dfd31d4 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,8 @@ Available flags: - `--packet-mark=` Use this option if youtubeUnblock conflicts with other systems rely on packet mark. Note that you may want to change accept rule for iptables to follow the mark. +- `--fbegin` and `--fend` flags: youtubeUnblock supports multiple sets of strategies for specific filters. You may want to initiate a new set after the default one, like: `--sni-domains=googlevideo.com --faking-strategy=md5sum --fbegin --sni-domains=youtube.com --faking-strategy=tcp_check --fend --fbegin --sni-domains=l.google.com --faking-strategy=pastseq --fend`. Note, that the priority of these sets goes backwards: last is first, default (one that does not start with --fbegin) is last. If you start the new section, the default settings are implemented just like youtubeUnblock without any parameters. Note that the config above is just an example and won't work for you. + ## Troubleshooting If you got troubles with some sites and you sure that they are blocked by SNI (youtube for example), use may play around with [flags](#flags) and their combinations. At first it is recommended to try `--faking-strategy` flag and `--frag-sni-faked=1`. diff --git a/args.c b/args.c index 9243103..c7ac2c0 100644 --- a/args.c +++ b/args.c @@ -12,8 +12,7 @@ static char custom_fake_buf[MAX_FAKE_SIZE]; -struct config_t config = { - .threads = THREADS_NUM, +static const struct section_config_t default_section_config = { .frag_sni_reverse = 1, .frag_sni_faked = 0, .fragmentation_strategy = FRAGMENTATION_STRATEGY, @@ -24,31 +23,12 @@ struct config_t config = { .fake_sni_type = FAKE_PAYLOAD_DEFAULT, .frag_middle_sni = 1, .frag_sni_pos = 1, - .use_ipv6 = 1, .fakeseq_offset = 10000, - .mark = DEFAULT_RAWSOCKET_MARK, .synfake = 0, .synfake_len = 0, + .quic_drop = 0, - .sni_detection = SNI_DETECTION_PARSE, - -#ifdef SEG2_DELAY - .seg2_delay = SEG2_DELAY, -#else .seg2_delay = 0, -#endif - -#ifdef USE_GSO - .use_gso = true, -#else - .use_gso = false, -#endif - -#ifdef DEBUG - .verbose = 1, -#else - .verbose = 0, -#endif .domains_str = defaul_snistr, .domains_strlen = sizeof(defaul_snistr), @@ -56,11 +36,25 @@ struct config_t config = { .exclude_domains_str = "", .exclude_domains_strlen = 0, - .queue_start_num = DEFAULT_QUEUE_NUM, .fake_sni_pkt = fake_sni_old, .fake_sni_pkt_sz = sizeof(fake_sni_old) - 1, // - 1 for null-terminator .fake_custom_pkt = custom_fake_buf, - .fake_custom_pkt_sz = 0 + .fake_custom_pkt_sz = 0, + + .sni_detection = SNI_DETECTION_PARSE, +}; + +struct config_t config = { + .threads = THREADS_NUM, + .queue_start_num = DEFAULT_QUEUE_NUM, + .mark = DEFAULT_RAWSOCKET_MARK, + .use_ipv6 = 1, + + .verbose = VERBOSE_DEBUG, + .use_gso = true, + + .default_config = default_section_config, + .custom_configs_len = 0 }; #define OPT_SNI_DOMAINS 1 @@ -71,6 +65,8 @@ struct config_t config = { #define OPT_FAKE_SNI_SEQ_LEN 11 #define OPT_FAKE_SNI_TYPE 27 #define OPT_FAKE_CUSTOM_PAYLOAD 28 +#define OPT_START_SECTION 29 +#define OPT_END_SECTION 30 #define OPT_FRAG 4 #define OPT_FRAG_SNI_REVERSE 12 #define OPT_FRAG_SNI_FAKED 13 @@ -91,7 +87,7 @@ struct config_t config = { #define OPT_NO_GSO 8 #define OPT_QUEUE_NUM 9 -#define OPT_MAX OPT_FAKE_CUSTOM_PAYLOAD +#define OPT_MAX OPT_END_SECTION static struct option long_opt[] = { {"help", 0, 0, 'h'}, @@ -123,6 +119,8 @@ static struct option long_opt[] = { {"no-ipv6", 0, 0, OPT_NO_IPV6}, {"queue-num", 1, 0, OPT_QUEUE_NUM}, {"packet-mark", 1, 0, OPT_PACKET_MARK}, + {"fbegin", 0, 0, OPT_START_SECTION}, + {"fend", 0, 0, OPT_END_SECTION}, {0,0,0,0} }; @@ -182,16 +180,27 @@ void print_usage(const char *argv0) { printf("\t--trace\n"); printf("\t--no-gso\n"); printf("\t--no-ipv6\n"); + printf("\t--fbegin\n"); + printf("\t--fend\n"); printf("\n"); } int parse_args(int argc, char *argv[]) { int opt; - int optIdx; + int optIdx = 0; long num; + struct section_config_t *sect_config = &config.default_config; + +#define SECT_ITER_DEFAULT 1 +#define SECT_ITER_INSIDE 2 +#define SECT_ITER_OUTSIDE 3 + + int section_iter = SECT_ITER_DEFAULT; + while ((opt = getopt_long(argc, argv, "hv", long_opt, &optIdx)) != -1) { switch (opt) { +/* config_t scoped configs */ case 'h': print_usage(argv[0]); goto stop_exec; @@ -199,49 +208,98 @@ int parse_args(int argc, char *argv[]) { print_version(); goto stop_exec; case OPT_TRACE: + if (section_iter != SECT_ITER_DEFAULT) + goto invalid_opt; config.verbose = 2; break; case OPT_SILENT: + if (section_iter != SECT_ITER_DEFAULT) + goto invalid_opt; + config.verbose = 0; break; case OPT_NO_GSO: + if (section_iter != SECT_ITER_DEFAULT) + goto invalid_opt; + config.use_gso = 0; break; case OPT_NO_IPV6: + if (section_iter != SECT_ITER_DEFAULT) + goto invalid_opt; + config.use_ipv6 = 0; break; - case OPT_QUIC_DROP: - config.quic_drop = 1; - break; - case OPT_SNI_DOMAINS: - if (!strcmp(optarg, "all")) { - config.all_domains = 1; - } + case OPT_THREADS: + if (section_iter != SECT_ITER_DEFAULT) + goto invalid_opt; - config.domains_str = optarg; - config.domains_strlen = strlen(config.domains_str); - break; - case OPT_EXCLUDE_DOMAINS: - config.exclude_domains_str = optarg; - config.exclude_domains_strlen = strlen(config.exclude_domains_str); - break; - case OPT_SNI_DETECTION: - if (strcmp(optarg, "parse") == 0) { - config.sni_detection = SNI_DETECTION_PARSE; - } else if (strcmp(optarg, "brute") == 0) { - config.sni_detection = SNI_DETECTION_BRUTE; - } else { + num = parse_numeric_option(optarg); + if (errno != 0 || num < 0 || num > MAX_THREADS) { goto invalid_opt; } + config.threads = num; + break; + case OPT_QUEUE_NUM: + if (section_iter != SECT_ITER_DEFAULT) + goto invalid_opt; + + num = parse_numeric_option(optarg); + if (errno != 0 || num < 0) { + goto invalid_opt; + } + + config.queue_start_num = num; + break; + case OPT_PACKET_MARK: + if (section_iter != SECT_ITER_DEFAULT) + goto invalid_opt; + + num = parse_numeric_option(optarg); + if (errno != 0 || num < 0) { + goto invalid_opt; + } + + config.mark = num; + break; + case OPT_START_SECTION: + if (section_iter != SECT_ITER_DEFAULT && section_iter != SECT_ITER_OUTSIDE) + goto invalid_opt; + + sect_config = &config.custom_configs[config.custom_configs_len++]; + *sect_config = default_section_config; + section_iter = SECT_ITER_INSIDE; + + break; + case OPT_END_SECTION: + if (section_iter != SECT_ITER_INSIDE) + goto invalid_opt; + + section_iter = SECT_ITER_OUTSIDE; + sect_config = &config.default_config; + break; + +/* section_config_t scoped configs */ + case OPT_SNI_DOMAINS: + if (!strcmp(optarg, "all")) { + sect_config->all_domains = 1; + } + + sect_config->domains_str = optarg; + sect_config->domains_strlen = strlen(sect_config->domains_str); + break; + case OPT_EXCLUDE_DOMAINS: + sect_config->exclude_domains_str = optarg; + sect_config->exclude_domains_strlen = strlen(sect_config->exclude_domains_str); break; case OPT_FRAG: if (strcmp(optarg, "tcp") == 0) { - config.fragmentation_strategy = FRAG_STRAT_TCP; + sect_config->fragmentation_strategy = FRAG_STRAT_TCP; } else if (strcmp(optarg, "ip") == 0) { - config.fragmentation_strategy = FRAG_STRAT_IP; + sect_config->fragmentation_strategy = FRAG_STRAT_IP; } else if (strcmp(optarg, "none") == 0) { - config.fragmentation_strategy = FRAG_STRAT_NONE; + sect_config->fragmentation_strategy = FRAG_STRAT_NONE; } else { goto invalid_opt; } @@ -249,9 +307,9 @@ int parse_args(int argc, char *argv[]) { break; case OPT_FRAG_SNI_FAKED: if (strcmp(optarg, "1") == 0) { - config.frag_sni_faked = 1; + sect_config->frag_sni_faked = 1; } else if (strcmp(optarg, "0") == 0) { - config.frag_sni_faked = 0; + sect_config->frag_sni_faked = 0; } else { goto invalid_opt; } @@ -259,9 +317,9 @@ int parse_args(int argc, char *argv[]) { break; case OPT_FRAG_SNI_REVERSE: if (strcmp(optarg, "1") == 0) { - config.frag_sni_reverse = 1; + sect_config->frag_sni_reverse = 1; } else if (strcmp(optarg, "0") == 0) { - config.frag_sni_reverse = 0; + sect_config->frag_sni_reverse = 0; } else { goto invalid_opt; } @@ -269,9 +327,9 @@ int parse_args(int argc, char *argv[]) { break; case OPT_FRAG_MIDDLE_SNI: if (strcmp(optarg, "1") == 0) { - config.frag_middle_sni = 1; + sect_config->frag_middle_sni = 1; } else if (strcmp(optarg, "0") == 0) { - config.frag_middle_sni = 0; + sect_config->frag_middle_sni = 0; } else { goto invalid_opt; } @@ -283,19 +341,19 @@ int parse_args(int argc, char *argv[]) { goto invalid_opt; } - config.frag_sni_pos = num; + sect_config->frag_sni_pos = num; break; case OPT_FAKING_STRATEGY: if (strcmp(optarg, "randseq") == 0) { - config.faking_strategy = FAKE_STRAT_RAND_SEQ; + sect_config->faking_strategy = FAKE_STRAT_RAND_SEQ; } else if (strcmp(optarg, "ttl") == 0) { - config.faking_strategy = FAKE_STRAT_TTL; + sect_config->faking_strategy = FAKE_STRAT_TTL; } else if (strcmp(optarg, "tcp_check") == 0) { - config.faking_strategy = FAKE_STRAT_TCP_CHECK; + sect_config->faking_strategy = FAKE_STRAT_TCP_CHECK; } else if (strcmp(optarg, "pastseq") == 0) { - config.faking_strategy = FAKE_STRAT_PAST_SEQ; + sect_config->faking_strategy = FAKE_STRAT_PAST_SEQ; } else if (strcmp(optarg, "md5sum") == 0) { - config.faking_strategy = FAKE_STRAT_TCP_MD5SUM; + sect_config->faking_strategy = FAKE_STRAT_TCP_MD5SUM; } else { goto invalid_opt; } @@ -307,7 +365,7 @@ int parse_args(int argc, char *argv[]) { goto invalid_opt; } - config.faking_ttl = num; + sect_config->faking_ttl = num; break; case OPT_FAKE_SEQ_OFFSET: num = parse_numeric_option(optarg); @@ -315,13 +373,13 @@ int parse_args(int argc, char *argv[]) { goto invalid_opt; } - config.fakeseq_offset = num; + sect_config->fakeseq_offset = num; break; case OPT_FAKE_SNI: if (strcmp(optarg, "1") == 0) { - config.fake_sni = 1; + sect_config->fake_sni = 1; } else if (strcmp(optarg, "0") == 0) { - config.fake_sni = 0; + sect_config->fake_sni = 0; } else { goto invalid_opt; } @@ -333,15 +391,15 @@ int parse_args(int argc, char *argv[]) { goto invalid_opt; } - config.fake_sni_seq_len = num; + sect_config->fake_sni_seq_len = num; break; case OPT_FAKE_SNI_TYPE: if (strcmp(optarg, "default") == 0) { - config.fake_sni_type = FAKE_PAYLOAD_DEFAULT; + sect_config->fake_sni_type = FAKE_PAYLOAD_DEFAULT; } else if (strcmp(optarg, "random") == 0) { - config.fake_sni_type = FAKE_PAYLOAD_RANDOM; + sect_config->fake_sni_type = FAKE_PAYLOAD_RANDOM; } else if (strcmp(optarg, "custom") == 0) { - config.fake_sni_type = FAKE_PAYLOAD_CUSTOM; + sect_config->fake_sni_type = FAKE_PAYLOAD_CUSTOM; } else { goto invalid_opt; } @@ -368,8 +426,8 @@ int parse_args(int argc, char *argv[]) { sscanf(custom_hex_fake + (i << 1), "%2hhx", custom_buf + i); } - config.fake_custom_pkt_sz = custom_len; - config.fake_custom_pkt = (char *)custom_buf; + sect_config->fake_custom_pkt_sz = custom_len; + sect_config->fake_custom_pkt = (char *)custom_buf; } break; case OPT_FK_WINSIZE: @@ -378,66 +436,37 @@ int parse_args(int argc, char *argv[]) { goto invalid_opt; } - config.fk_winsize = num; + sect_config->fk_winsize = num; break; - case OPT_SYNFAKE: - if (strcmp(optarg, "1") == 0) { - config.synfake = 1; - } else if (strcmp(optarg, "0") == 0) { - config.synfake = 0; - } else { - goto invalid_opt; - } - break; - case OPT_SYNFAKE_LEN: - num = parse_numeric_option(optarg); - if (errno != 0 || num < 0) { - goto invalid_opt; - } - - config.synfake_len = num; - break; case OPT_SEG2DELAY: num = parse_numeric_option(optarg); if (errno != 0 || num < 0) { goto invalid_opt; } - config.seg2_delay = num; + sect_config->seg2_delay = num; break; - case OPT_THREADS: - num = parse_numeric_option(optarg); - if (errno != 0 || num < 0 || num > MAX_THREADS) { + case OPT_QUIC_DROP: + sect_config->quic_drop = 1; + break; + case OPT_SNI_DETECTION: + if (strcmp(optarg, "parse") == 0) { + sect_config->sni_detection = SNI_DETECTION_PARSE; + } else if (strcmp(optarg, "brute") == 0) { + sect_config->sni_detection = SNI_DETECTION_BRUTE; + } else { goto invalid_opt; } - config.threads = num; break; - case OPT_QUEUE_NUM: - num = parse_numeric_option(optarg); - if (errno != 0 || num < 0) { - goto invalid_opt; - } - - config.queue_start_num = num; - break; - case OPT_PACKET_MARK: - num = parse_numeric_option(optarg); - if (errno != 0 || num < 0) { - goto invalid_opt; - } - - config.mark = num; - break; - default: goto error; } + } -// out: errno = 0; return 0; stop_exec: @@ -453,68 +482,6 @@ error: } void print_welcome() { - switch (config.fragmentation_strategy) { - case FRAG_STRAT_TCP: - printf("Using TCP segmentation\n"); - break; - case FRAG_STRAT_IP: - printf("Using IP fragmentation\n"); - break; - default: - printf("SNI fragmentation is disabled\n"); - break; - } - - if (config.seg2_delay) { - printf("Some outgoing googlevideo request segments will be delayed for %d ms as of seg2_delay define\n", config.seg2_delay); - } - - if (config.fake_sni) { - printf("Fake SNI will be sent before each target client hello\n"); - } else { - printf("Fake SNI is disabled\n"); - } - - if (config.frag_sni_reverse) { - printf("Fragmentation Client Hello will be reversed\n"); - } - - if (config.frag_sni_faked) { - printf("Fooling packets will be sent near the original Client Hello\n"); - } - - if (config.fake_sni_seq_len > 1) { - printf("Faking sequence of length %d will be built as fake sni\n", config.fake_sni_seq_len); - } - - switch (config.faking_strategy) { - case FAKE_STRAT_TTL: - printf("TTL faking strategy will be used with TTL %d\n", config.faking_ttl); - break; - case FAKE_STRAT_RAND_SEQ: - printf("Random seq faking strategy will be used\n"); - printf("Fake seq offset set to %u\n", config.fakeseq_offset); - break; - case FAKE_STRAT_TCP_CHECK: - printf("TCP checksum faking strategy will be used\n"); - break; - case FAKE_STRAT_PAST_SEQ: - printf("Past seq faking strategy will be used\n"); - break; - case FAKE_STRAT_TCP_MD5SUM: - printf("md5sum faking strategy will be used\n"); - break; - } - - if (config.fk_winsize) { - printf("Response TCP window will be set to %d with the appropriate scale\n", config.fk_winsize); - } - - if (config.synfake) { - printf("Fake SYN payload will be sent with each TCP request SYN packet\n"); - } - - if (config.use_gso) { printf("GSO is enabled\n"); } @@ -524,18 +491,88 @@ void print_welcome() { } else { printf("IPv6 is disabled\n"); } + + printf("Detected %d config sections\n", config.custom_configs_len + 1); + printf("The sections will be processed in ordred they goes in this output"); - if (config.quic_drop) { - printf("All QUIC packets will be dropped\n"); + ITER_CONFIG_SECTIONS(section) { + int section_number = CONFIG_SECTION_NUMBER(section); + printf("Section #%d\n", section_number); + + switch (section->fragmentation_strategy) { + case FRAG_STRAT_TCP: + printf("Using TCP segmentation\n"); + break; + case FRAG_STRAT_IP: + printf("Using IP fragmentation\n"); + break; + default: + printf("SNI fragmentation is disabled\n"); + break; + } + + if (section->seg2_delay) { + printf("Some outgoing googlevideo request segments will be delayed for %d ms as of seg2_delay define\n", section->seg2_delay); + } + + if (section->fake_sni) { + printf("Fake SNI will be sent before each target client hello\n"); + } else { + printf("Fake SNI is disabled\n"); + } + + if (section->frag_sni_reverse) { + printf("Fragmentation Client Hello will be reversed\n"); + } + + if (section->frag_sni_faked) { + printf("Fooling packets will be sent near the original Client Hello\n"); + } + + if (section->fake_sni_seq_len > 1) { + printf("Faking sequence of length %d will be built as fake sni\n", section->fake_sni_seq_len); + } + + switch (section->faking_strategy) { + case FAKE_STRAT_TTL: + printf("TTL faking strategy will be used with TTL %d\n", section->faking_ttl); + break; + case FAKE_STRAT_RAND_SEQ: + printf("Random seq faking strategy will be used\n"); + printf("Fake seq offset set to %u\n", section->fakeseq_offset); + break; + case FAKE_STRAT_TCP_CHECK: + printf("TCP checksum faking strategy will be used\n"); + break; + case FAKE_STRAT_PAST_SEQ: + printf("Past seq faking strategy will be used\n"); + break; + case FAKE_STRAT_TCP_MD5SUM: + printf("md5sum faking strategy will be used\n"); + break; + } + + if (section->fk_winsize) { + printf("Response TCP window will be set to %d with the appropriate scale\n", section->fk_winsize); + } + + if (section->synfake) { + printf("Fake SYN payload will be sent with each TCP request SYN packet\n"); + } + + if (section->quic_drop) { + printf("All QUIC packets will be dropped\n"); + } + + if (section->sni_detection == SNI_DETECTION_BRUTE) { + printf("Server Name Extension will be parsed in the bruteforce mode\n"); + } + + if (section->all_domains) { + printf("All Client Hello will be targetted by youtubeUnblock!\n"); + } else { + printf("Target sni domains: %s\n", section->domains_str); + } } - - if (config.sni_detection == SNI_DETECTION_BRUTE) { - printf("Server Name Extension will be parsed in the bruteforce mode\n"); - } - - if (config.all_domains) { - printf("All Client Hello will be targetted by youtubeUnblock!\n"); - } - } diff --git a/config.h b/config.h index 8d0d55d..086a289 100644 --- a/config.h +++ b/config.h @@ -18,11 +18,10 @@ struct instance_config_t { }; extern struct instance_config_t instance_config; -struct config_t { - unsigned int queue_start_num; - int threads; - int use_gso; - int use_ipv6; +struct section_config_t { + const char *domains_str; + unsigned int domains_strlen; + int fragmentation_strategy; int frag_sni_reverse; int frag_sni_faked; @@ -39,18 +38,13 @@ struct config_t { #define FAKE_PAYLOAD_DEFAULT 2 int fake_sni_type; -#define VERBOSE_INFO 0 -#define VERBOSE_DEBUG 1 -#define VERBOSE_TRACE 2 - int verbose; int quic_drop; -#define SNI_DETECTION_PARSE 0 -#define SNI_DETECTION_BRUTE 1 - int sni_detection; + /* In milliseconds */ unsigned int seg2_delay; - const char *domains_str; - unsigned int domains_strlen; + int synfake; + unsigned int synfake_len; + const char *exclude_domains_str; unsigned int exclude_domains_strlen; unsigned int all_domains; @@ -61,16 +55,42 @@ struct config_t { const char *fake_custom_pkt; unsigned int fake_custom_pkt_sz; - unsigned int fk_winsize; int fakeseq_offset; + +#define SNI_DETECTION_PARSE 0 +#define SNI_DETECTION_BRUTE 1 + int sni_detection; + + +}; + +#define MAX_CONFIGLIST_LEN 64 + +struct config_t { + unsigned int queue_start_num; + int threads; + int use_gso; + int use_ipv6; unsigned int mark; - int synfake; - unsigned int synfake_len; + +#define VERBOSE_INFO 0 +#define VERBOSE_DEBUG 1 +#define VERBOSE_TRACE 2 + int verbose; + + struct section_config_t default_config; + struct section_config_t custom_configs[MAX_CONFIGLIST_LEN]; + int custom_configs_len; }; extern struct config_t config; +#define ITER_CONFIG_SECTIONS(section) \ +for (struct section_config_t *section = &config.default_config + config.custom_configs_len; section >= &config.default_config; section--) + +#define CONFIG_SECTION_NUMBER(section) (int)((section) - &config.default_config) + #define MAX_THREADS 16 #ifndef THREADS_NUM diff --git a/kargs.c b/kargs.c index 8b63f31..953118f 100644 --- a/kargs.c +++ b/kargs.c @@ -4,11 +4,11 @@ #include #include "types.h" -static char custom_fake_buf[MAX_FAKE_SIZE]; - #define STR_MAXLEN 2048 -struct config_t config = { +static char custom_fake_buf[MAX_FAKE_SIZE]; + +static const struct section_config_t default_section_config = { .frag_sni_reverse = 1, .frag_sni_faked = 0, .fragmentation_strategy = FRAGMENTATION_STRATEGY, @@ -16,45 +16,44 @@ struct config_t config = { .faking_ttl = FAKE_TTL, .fake_sni = 1, .fake_sni_seq_len = 1, + .fake_sni_type = FAKE_PAYLOAD_DEFAULT, .frag_middle_sni = 1, .frag_sni_pos = 1, - .use_ipv6 = 1, .fakeseq_offset = 10000, - .mark = DEFAULT_RAWSOCKET_MARK, .synfake = 0, .synfake_len = 0, - .fake_sni_type = FAKE_PAYLOAD_DEFAULT, + .quic_drop = 0, - .sni_detection = SNI_DETECTION_PARSE, - -#ifdef SEG2_DELAY - .seg2_delay = SEG2_DELAY, -#else .seg2_delay = 0, -#endif - -#ifdef USE_GSO - .use_gso = 1, -#else - .use_gso = false, -#endif - -#ifdef DEBUG - .verbose = 2, -#else - .verbose = 1, -#endif .domains_str = defaul_snistr, .domains_strlen = sizeof(defaul_snistr), - .queue_start_num = DEFAULT_QUEUE_NUM, + .exclude_domains_str = "", + .exclude_domains_strlen = 0, + .fake_sni_pkt = fake_sni_old, .fake_sni_pkt_sz = sizeof(fake_sni_old) - 1, // - 1 for null-terminator .fake_custom_pkt = custom_fake_buf, - .fake_custom_pkt_sz = 0 + .fake_custom_pkt_sz = 0, + .sni_detection = SNI_DETECTION_PARSE, }; +struct config_t config = { + .threads = THREADS_NUM, + .queue_start_num = DEFAULT_QUEUE_NUM, + .mark = DEFAULT_RAWSOCKET_MARK, + .use_ipv6 = 1, + + .verbose = VERBOSE_DEBUG, + .use_gso = 1, + + .default_config = default_section_config, + .custom_configs_len = 0 +}; + +static struct section_config_t *const def_section = &config.default_config; + static int unumeric_set(const char *val, const struct kernel_param *kp) { int n = 0, ret; ret = kstrtoint(val, 10, &n); @@ -113,19 +112,19 @@ static const struct kernel_param_ops inverse_boolean_ops = { .get = inverse_boolean_get, }; -module_param_cb(fake_sni, &boolean_parameter_ops, &config.fake_sni, 0664); -module_param_cb(fake_sni_seq_len, &unumeric_parameter_ops, &config.fake_sni_seq_len, 0664); -module_param_cb(faking_ttl, &unumeric_parameter_ops, &config.faking_ttl, 0664); -module_param_cb(fake_seq_offset, &unumeric_parameter_ops, &config.fakeseq_offset, 0664); -module_param_cb(frag_sni_reverse, &unumeric_parameter_ops, &config.frag_sni_reverse, 0664); -module_param_cb(frag_sni_faked, &boolean_parameter_ops, &config.frag_sni_faked, 0664); -module_param_cb(frag_middle_sni, &boolean_parameter_ops, &config.frag_middle_sni, 0664); -module_param_cb(frag_sni_pos, &unumeric_parameter_ops, &config.frag_sni_pos, 0664); -module_param_cb(fk_winsize, &unumeric_parameter_ops, &config.fk_winsize, 0664); -module_param_cb(synfake, &boolean_parameter_ops, &config.synfake, 0664); -module_param_cb(synfake_len, &unumeric_parameter_ops, &config.synfake_len, 0664); +module_param_cb(fake_sni, &boolean_parameter_ops, &def_section->fake_sni, 0664); +module_param_cb(fake_sni_seq_len, &unumeric_parameter_ops, &def_section->fake_sni_seq_len, 0664); +module_param_cb(faking_ttl, &unumeric_parameter_ops, &def_section->faking_ttl, 0664); +module_param_cb(fake_seq_offset, &unumeric_parameter_ops, &def_section->fakeseq_offset, 0664); +module_param_cb(frag_sni_reverse, &unumeric_parameter_ops, &def_section->frag_sni_reverse, 0664); +module_param_cb(frag_sni_faked, &boolean_parameter_ops, &def_section->frag_sni_faked, 0664); +module_param_cb(frag_middle_sni, &boolean_parameter_ops, &def_section->frag_middle_sni, 0664); +module_param_cb(frag_sni_pos, &unumeric_parameter_ops, &def_section->frag_sni_pos, 0664); +module_param_cb(fk_winsize, &unumeric_parameter_ops, &def_section->fk_winsize, 0664); +module_param_cb(synfake, &boolean_parameter_ops, &def_section->synfake, 0664); +module_param_cb(synfake_len, &unumeric_parameter_ops, &def_section->synfake_len, 0664); module_param_cb(packet_mark, &unumeric_parameter_ops, &config.mark, 0664); -// module_param_cb(seg2delay, &unumeric_parameter_ops, &config.seg2_delay, 0664); +// module_param_cb(seg2delay, &unumeric_parameter_ops, &def_section->seg2_delay, 0664); static int sni_domains_set(const char *val, const struct kernel_param *kp) { size_t len; @@ -144,13 +143,13 @@ static int sni_domains_set(const char *val, const struct kernel_param *kp) { ret = param_set_charp(val, kp); if (ret < 0) { - config.domains_strlen = 0; + def_section->domains_strlen = 0; } else { - config.domains_strlen = len; + def_section->domains_strlen = len; if (len == 3 && !strncmp(val, "all", len)) { - config.all_domains = 1; + def_section->all_domains = 1; } else { - config.all_domains = 0; + def_section->all_domains = 0; } } @@ -163,7 +162,7 @@ static const struct kernel_param_ops sni_domains_ops = { .get = param_get_charp, }; -module_param_cb(sni_domains, &sni_domains_ops, &config.domains_str, 0664); +module_param_cb(sni_domains, &sni_domains_ops, &def_section->domains_str, 0664); static int exclude_domains_set(const char *val, const struct kernel_param *kp) { size_t len; @@ -178,9 +177,9 @@ static int exclude_domains_set(const char *val, const struct kernel_param *kp) { ret = param_set_charp(val, kp); if (ret < 0) { - config.exclude_domains_strlen = 0; + def_section->exclude_domains_strlen = 0; } else { - config.exclude_domains_strlen = len; + def_section->exclude_domains_strlen = len; } return ret; @@ -191,10 +190,10 @@ static const struct kernel_param_ops exclude_domains_ops = { .get = param_get_charp, }; -module_param_cb(exclude_domains, &exclude_domains_ops, &config.exclude_domains_str, 0664); +module_param_cb(exclude_domains, &exclude_domains_ops, &def_section->exclude_domains_str, 0664); module_param_cb(no_ipv6, &inverse_boolean_ops, &config.use_ipv6, 0664); -module_param_cb(quic_drop, &boolean_parameter_ops, &config.quic_drop, 0664); +module_param_cb(quic_drop, &boolean_parameter_ops, &def_section->quic_drop, 0664); static int verbosity_set(const char *val, const struct kernel_param *kp) { size_t len; @@ -297,7 +296,7 @@ static const struct kernel_param_ops frag_strat_ops = { .get = frag_strat_get, }; -module_param_cb(fragmentation_strategy, &frag_strat_ops, &config.fragmentation_strategy, 0664); +module_param_cb(fragmentation_strategy, &frag_strat_ops, &def_section->fragmentation_strategy, 0664); static int fake_strat_set(const char *val, const struct kernel_param *kp) { size_t len; @@ -358,7 +357,7 @@ static const struct kernel_param_ops fake_strat_ops = { .get = fake_strat_get, }; -module_param_cb(faking_strategy, &fake_strat_ops, &config.faking_strategy, 0664); +module_param_cb(faking_strategy, &fake_strat_ops, &def_section->faking_strategy, 0664); static int sni_detection_set(const char *val, const struct kernel_param *kp) { size_t len; @@ -404,7 +403,7 @@ static const struct kernel_param_ops sni_detection_ops = { .get = sni_detection_get, }; -module_param_cb(sni_detection, &sni_detection_ops, &config.sni_detection, 0664); +module_param_cb(sni_detection, &sni_detection_ops, &def_section->sni_detection, 0664); static int fake_type_set(const char *val, const struct kernel_param *kp) { size_t len; @@ -455,7 +454,7 @@ static const struct kernel_param_ops fake_type_ops = { .get = fake_type_get, }; -module_param_cb(fake_sni_type, &fake_type_ops, &config.fake_sni_type, 0664); +module_param_cb(fake_sni_type, &fake_type_ops, &def_section->fake_sni_type, 0664); static int fake_custom_pl_set(const char *val, const struct kernel_param *kp) { size_t len; @@ -488,16 +487,16 @@ static int fake_custom_pl_set(const char *val, const struct kernel_param *kp) { sscanf(custom_hex_fake + (i << 1), "%2hhx", custom_buf + i); } - config.fake_custom_pkt_sz = custom_len; - config.fake_custom_pkt = (char *)custom_buf; + def_section->fake_custom_pkt_sz = custom_len; + def_section->fake_custom_pkt = (char *)custom_buf; return 0; } static int fake_custom_pl_get(char *buffer, const struct kernel_param *kp) { - int cflen = config.fake_custom_pkt_sz; - const uint8_t *cbf_data = config.fake_custom_pkt; - int bflen = config.fake_custom_pkt_sz << 1; + int cflen = def_section->fake_custom_pkt_sz; + const uint8_t *cbf_data = def_section->fake_custom_pkt; + int bflen = def_section->fake_custom_pkt_sz << 1; for (int i = 0; i < cflen; i++) { sprintf(buffer + (i << 1), "%02x", *((unsigned char *)cbf_data + i)); @@ -511,4 +510,4 @@ static const struct kernel_param_ops fake_custom_pl_ops = { .get = fake_custom_pl_get, }; -module_param_cb(fake_custom_payload, &fake_custom_pl_ops, &config.fake_custom_pkt, 0664); +module_param_cb(fake_custom_payload, &fake_custom_pl_ops, &def_section->fake_custom_pkt, 0664); diff --git a/kytunblock.c b/kytunblock.c index aa01183..c473018 100644 --- a/kytunblock.c +++ b/kytunblock.c @@ -171,25 +171,10 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) { uint32_t buff1_size = MAX_PACKET_SIZE; uint32_t buff2_size = MAX_PACKET_SIZE; - switch (config.fragmentation_strategy) { - case FRAG_STRAT_TCP: - if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128, - buff1, &buff1_size, buff2, &buff2_size)) < 0) { + if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128, + buff1, &buff1_size, buff2, &buff2_size)) < 0) { - goto erret_lc; - } - break; - case FRAG_STRAT_IP: - if ((ret = ip4_frag(pkt, pktlen, AVAILABLE_MTU-128, - buff1, &buff1_size, buff2, &buff2_size)) < 0) { - - goto erret_lc; - } - break; - default: - pr_info("send_raw_socket: Packet is too big but fragmentation is disabled!"); - ret = -EINVAL; - goto erret_lc; + goto erret_lc; } int sent = 0; diff --git a/mangle.c b/mangle.c index d28cbc5..ca3b65b 100644 --- a/mangle.c +++ b/mangle.c @@ -26,6 +26,8 @@ int process_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { int ipver = netproto_version(raw_payload, raw_payload_len); int ret; + lgtrace_start(); + lgtrace_addp("IPv%d", ipver); if (ipver == IP4VERSION) { ret = ip4_payload_split((uint8_t *)raw_payload, raw_payload_len, @@ -52,21 +54,39 @@ int process_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { goto accept; } + int verdict = PKT_CONTINUE; + + if (transport_proto == IPPROTO_TCP) + lgtrace_addp("TCP"); + else if (transport_proto == IPPROTO_UDP) + lgtrace_addp("UDP"); + - switch (transport_proto) { - case IPPROTO_TCP: - return process_tcp_packet(raw_payload, raw_payload_len); - case IPPROTO_UDP: - return process_udp_packet(raw_payload, raw_payload_len); - default: - goto accept; + ITER_CONFIG_SECTIONS(section) { + lgtrace_addp("Section #%d", CONFIG_SECTION_NUMBER(section)); + + switch (transport_proto) { + case IPPROTO_TCP: + verdict = process_tcp_packet(section, raw_payload, raw_payload_len); + break; + case IPPROTO_UDP: + verdict = process_udp_packet(section, raw_payload, raw_payload_len); + break; + } + + if (verdict == PKT_CONTINUE) + continue; + + lgtrace_end(); + return verdict; } - -accept: + +accept: + lgtrace_end(); return PKT_ACCEPT; } -int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { +int process_tcp_packet(const struct section_config_t *section, const uint8_t *raw_payload, uint32_t raw_payload_len) { const void *ipxh; uint32_t iph_len; const struct tcphdr *tcph; @@ -77,9 +97,6 @@ int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { int ipxv = netproto_version(raw_payload, raw_payload_len); - lgtrace_start("TCP"); - lgtrace_addp("IPv%d", ipxv); - int ret = tcp_payload_split((uint8_t *)raw_payload, raw_payload_len, (void *)&ipxh, &iph_len, (struct tcphdr **)&tcph, &tcph_len, @@ -90,7 +107,7 @@ int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { goto accept; } - if (tcph->syn && config.synfake) { + if (tcph->syn && section->synfake) { lgtrace_addp("TCP syn alter"); NETBUF_ALLOC(payload, MAX_PACKET_SIZE); @@ -101,12 +118,12 @@ int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { memcpy(payload, ipxh, iph_len); memcpy(payload + iph_len, tcph, tcph_len); - uint32_t fake_len = config.fake_sni_pkt_sz; + uint32_t fake_len = section->fake_sni_pkt_sz; - if (config.synfake_len) - fake_len = min(config.synfake_len, fake_len); + if (section->synfake_len) + fake_len = min(section->synfake_len, fake_len); - memcpy(payload + iph_len + tcph_len, config.fake_sni_pkt, fake_len); + memcpy(payload + iph_len + tcph_len, section->fake_sni_pkt, fake_len); struct tcphdr *tcph = (struct tcphdr *)(payload + iph_len); @@ -130,16 +147,15 @@ int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { NETBUF_FREE(payload); goto accept; } - lgtrace_addp("rawsocket sent %d", ret); NETBUF_FREE(payload); goto drop; } - if (tcph->syn) goto accept; + if (tcph->syn) goto continue_flow; - struct tls_verdict vrd = analyze_tls_data(data, dlen); - lgtrace_addp("Analyzed"); + struct tls_verdict vrd = analyze_tls_data(section, data, dlen); + lgtrace_addp("TLS analyzed"); if (vrd.sni_len != 0) { lgtrace_addp("SNI detected: %.*s", vrd.sni_len, data + vrd.sni_offset); @@ -173,8 +189,8 @@ int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { goto accept_lc; } - if (config.fk_winsize) { - tcph->window = htons(config.fk_winsize); + if (section->fk_winsize) { + tcph->window = htons(section->fk_winsize); set_tcp_checksum(tcph, iph, iph_len); } @@ -194,14 +210,14 @@ int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { lgdebugmsg("WARNING! Client Hello packet is too big and may cause issues!"); } - if (config.fake_sni) { - post_fake_sni(args_default_fake_type(), iph, iph_len, tcph, tcph_len); + if (section->fake_sni) { + post_fake_sni(args_default_fake_type(section), iph, iph_len, tcph, tcph_len); } size_t ipd_offset; size_t mid_offset; - switch (config.fragmentation_strategy) { + switch (section->fragmentation_strategy) { case FRAG_STRAT_TCP: { ipd_offset = vrd.sni_target_offset; mid_offset = ipd_offset + vrd.sni_target_len / 2; @@ -209,11 +225,11 @@ int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { uint32_t poses[2]; int cnt = 0; - if (config.frag_sni_pos && dlen > config.frag_sni_pos) { - poses[cnt++] = config.frag_sni_pos; + if (section->frag_sni_pos && dlen > section->frag_sni_pos) { + poses[cnt++] = section->frag_sni_pos; } - if (config.frag_middle_sni) { + if (section->frag_middle_sni) { poses[cnt++] = mid_offset; } @@ -223,7 +239,7 @@ int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { poses[1] = tmp; } - ret = send_tcp_frags(payload, payload_len, poses, cnt, 0); + ret = send_tcp_frags(section, payload, payload_len, poses, cnt, 0); if (ret < 0) { lgerror("tcp4 send frags", ret); goto accept_lc; @@ -241,13 +257,13 @@ int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { uint32_t poses[2]; int cnt = 0; - if (config.frag_sni_pos && dlen > config.frag_sni_pos) { - poses[cnt] = config.frag_sni_pos + ((char *)data - (char *)tcph); + if (section->frag_sni_pos && dlen > section->frag_sni_pos) { + poses[cnt] = section->frag_sni_pos + ((char *)data - (char *)tcph); poses[cnt] += 8 - poses[cnt] % 8; cnt++; } - if (config.frag_middle_sni) { + if (section->frag_middle_sni) { poses[cnt++] = mid_offset; } @@ -257,7 +273,7 @@ int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) { poses[1] = tmp; } - ret = send_ip4_frags(payload, payload_len, poses, cnt, 0); + ret = send_ip4_frags(section, payload, payload_len, poses, cnt, 0); if (ret < 0) { lgerror("ip4 send frags", ret); goto accept_lc; @@ -292,27 +308,24 @@ drop_lc: } +continue_flow: + lgtrace_addp("continue_flow"); + return PKT_CONTINUE; accept: lgtrace_addp("accept"); - lgtrace_end(); - return PKT_ACCEPT; drop: lgtrace_addp("drop"); - lgtrace_end(); - return PKT_DROP; } -int process_udp_packet(const uint8_t *pkt, uint32_t pktlen) { +int process_udp_packet(const struct section_config_t *section, const uint8_t *pkt, uint32_t pktlen) { const void *iph; uint32_t iph_len; const struct udphdr *udph; const uint8_t *data; uint32_t dlen; int ipver = netproto_version(pkt, pktlen); - lgtrace_start("Got udp packet"); - lgtrace_addp("IPv%d", ipver); int ret = udp_payload_split((uint8_t *)pkt, pktlen, (void **)&iph, &iph_len, @@ -334,7 +347,7 @@ int process_udp_packet(const uint8_t *pkt, uint32_t pktlen) { } - if (config.quic_drop) { + if (section->quic_drop) { lgtrace_addp("QUIC probe"); const struct quic_lhdr *qch; uint32_t qch_len; @@ -368,9 +381,6 @@ int process_udp_packet(const uint8_t *pkt, uint32_t pktlen) { lgtrace_addp("quic initial message"); } -accept_quic: - ; - /* if (1) { lgtrace_addp("Probe udp"); @@ -402,29 +412,26 @@ accept_quic: */ - +continue_flow: + lgtrace_addp("continue_flow"); + return PKT_CONTINUE; +accept_quic: accept: - lgtrace_addp("accepted"); - lgtrace_end(); - return PKT_ACCEPT; drop: - lgtrace_addp("dropped"); - lgtrace_end(); - return PKT_DROP; } -int send_ip4_frags(const uint8_t *packet, uint32_t pktlen, const uint32_t *poses, uint32_t poses_sz, uint32_t dvs) { +int send_ip4_frags(const struct section_config_t *section, const uint8_t *packet, uint32_t pktlen, const uint32_t *poses, uint32_t poses_sz, uint32_t dvs) { if (poses_sz == 0) { - if (config.seg2_delay && ((dvs > 0) ^ config.frag_sni_reverse)) { + if (section->seg2_delay && ((dvs > 0) ^ section->frag_sni_reverse)) { if (!instance_config.send_delayed_packet) { return -EINVAL; } - lgtrace_addp("Sent %d delayed for %d", pktlen, config.seg2_delay); + lgtrace_addp("Sent %d delayed for %d", pktlen, section->seg2_delay); instance_config.send_delayed_packet( - packet, pktlen, config.seg2_delay); + packet, pktlen, section->seg2_delay); return 0; } else { @@ -479,21 +486,21 @@ int send_ip4_frags(const uint8_t *packet, uint32_t pktlen, const uint32_t *poses dvs += frag_pos; - if (config.frag_sni_reverse) + if (section->frag_sni_reverse) goto send_frag2; send_frag1: - ret = send_ip4_frags(frag1, f1len, NULL, 0, 0); + ret = send_ip4_frags(section, frag1, f1len, NULL, 0, 0); if (ret < 0) { goto erret_lc; } - if (config.frag_sni_reverse) + if (section->frag_sni_reverse) goto out_lc; send_fake: /* - if (config.frag_sni_faked) { - ITER_FAKE_STRAT(config.faking_strategy, strategy) { + if (section->frag_sni_faked) { + ITER_FAKE_STRAT(section->faking_strategy, strategy) { uint32_t iphfl; fake_pad_len = f2len; ret = ip4_payload_split(frag2, f2len, NULL, &iphfl, NULL, NULL); @@ -517,16 +524,16 @@ send_fake: } */ - if (config.frag_sni_reverse) + if (section->frag_sni_reverse) goto send_frag1; send_frag2: - ret = send_ip4_frags(frag2, f2len, poses + 1, poses_sz - 1, dvs); + ret = send_ip4_frags(section, frag2, f2len, poses + 1, poses_sz - 1, dvs); if (ret < 0) { goto erret_lc; } - if (config.frag_sni_reverse) + if (section->frag_sni_reverse) goto send_fake; out_lc: @@ -545,15 +552,15 @@ out: return 0; } -int send_tcp_frags(const uint8_t *packet, uint32_t pktlen, const uint32_t *poses, uint32_t poses_sz, uint32_t dvs) { +int send_tcp_frags(const struct section_config_t *section, const uint8_t *packet, uint32_t pktlen, const uint32_t *poses, uint32_t poses_sz, uint32_t dvs) { if (poses_sz == 0) { - if (config.seg2_delay && ((dvs > 0) ^ config.frag_sni_reverse)) { + if (section->seg2_delay && ((dvs > 0) ^ section->frag_sni_reverse)) { if (!instance_config.send_delayed_packet) { return -EINVAL; } instance_config.send_delayed_packet( - packet, pktlen, config.seg2_delay); + packet, pktlen, section->seg2_delay); return 0; } else { @@ -601,49 +608,49 @@ int send_tcp_frags(const uint8_t *packet, uint32_t pktlen, const uint32_t *poses dvs += poses[0]; - if (config.frag_sni_reverse) + if (section->frag_sni_reverse) goto send_frag2; send_frag1: { - ret = send_tcp_frags(frag1, f1len, NULL, 0, 0); + ret = send_tcp_frags(section, frag1, f1len, NULL, 0, 0); if (ret < 0) { goto erret_lc; } - if (config.frag_sni_reverse) + if (section->frag_sni_reverse) goto out_lc; } send_fake: - if (config.frag_sni_faked) { + if (section->frag_sni_faked) { uint32_t iphfl, tcphfl; void *iph; struct tcphdr *tcph; ret = tcp_payload_split(frag2, f2len, &iph, &iphfl, &tcph, &tcphfl, NULL, NULL); - struct fake_type f_type = args_default_fake_type(); + struct fake_type f_type = args_default_fake_type(section); if ((f_type.strategy.strategy & FAKE_STRAT_PAST_SEQ) == FAKE_STRAT_PAST_SEQ) { f_type.strategy.strategy ^= FAKE_STRAT_PAST_SEQ; f_type.strategy.strategy |= FAKE_STRAT_RAND_SEQ; f_type.strategy.randseq_offset = dvs; } - f_type.seg2delay = config.seg2_delay; + f_type.seg2delay = section->seg2_delay; post_fake_sni(f_type, iph, iphfl, tcph, tcphfl); } - if (config.frag_sni_reverse) + if (section->frag_sni_reverse) goto send_frag1; send_frag2: { - ret = send_tcp_frags(frag2, f2len, poses + 1, poses_sz - 1, dvs); + ret = send_tcp_frags(section, frag2, f2len, poses + 1, poses_sz - 1, dvs); if (ret < 0) { goto erret_lc; } - if (config.frag_sni_reverse) + if (section->frag_sni_reverse) goto send_fake; } out_lc: diff --git a/mangle.h b/mangle.h index aa503d3..0644d6c 100644 --- a/mangle.h +++ b/mangle.h @@ -6,6 +6,8 @@ #define PKT_ACCEPT 0 #define PKT_DROP 1 +// Used for section config +#define PKT_CONTINUE 2 /** * Processes the packet and returns verdict. @@ -18,14 +20,14 @@ int process_packet(const uint8_t *packet, uint32_t packet_len); * Processe the TCP packet. * Returns verdict. */ -int process_tcp_packet(const uint8_t *raw_payload, uint32_t raw_payload_len); +int process_tcp_packet(const struct section_config_t *section, const uint8_t *raw_payload, uint32_t raw_payload_len); /** * Processes the UDP packet. * Returns verdict. */ -int process_udp_packet(const uint8_t *pkt, uint32_t pktlen); +int process_udp_packet(const struct section_config_t *section, const uint8_t *pkt, uint32_t pktlen); @@ -41,7 +43,7 @@ int post_fake_sni(struct fake_type f_type, * Poses are relative to start of TCP payload. * dvs used internally and should be zero. */ -int send_tcp_frags( +int send_tcp_frags(const struct section_config_t *section, const uint8_t *packet, uint32_t pktlen, const uint32_t *poses, uint32_t poses_len, uint32_t dvs); @@ -50,7 +52,7 @@ int send_tcp_frags( * Poses are relative to start of TCP payload. * dvs used internally and should be zero. */ -int send_ip4_frags( +int send_ip4_frags(const struct section_config_t *section, const uint8_t *packet, uint32_t pktlen, const uint32_t *poses, uint32_t poses_len, uint32_t dvs); #endif /* YU_MANGLE_H */ diff --git a/tls.c b/tls.c index 6b13c3a..e67c18c 100644 --- a/tls.c +++ b/tls.c @@ -21,6 +21,7 @@ * dlen Length of `data`. */ struct tls_verdict analyze_tls_data( + const struct section_config_t *section, const uint8_t *data, uint32_t dlen) { @@ -43,7 +44,7 @@ struct tls_verdict analyze_tls_data( if (tls_content_type != TLS_CONTENT_TYPE_HANDSHAKE) goto nextMessage; - if (config.sni_detection == SNI_DETECTION_BRUTE) { + if (section->sni_detection == SNI_DETECTION_BRUTE) { goto brute; } @@ -126,22 +127,22 @@ struct tls_verdict analyze_tls_data( vrd.sni_len = sni_len; vrd.sni_target_len = vrd.sni_len; - if (config.all_domains) { + if (section->all_domains) { vrd.target_sni = 1; goto check_domain; } unsigned int j = 0; - for (unsigned int i = 0; i <= config.domains_strlen; i++) { + for (unsigned int i = 0; i <= section->domains_strlen; i++) { if ( i > j && - (i == config.domains_strlen || - config.domains_str[i] == '\0' || - config.domains_str[i] == ',' || - config.domains_str[i] == '\n' )) { + (i == section->domains_strlen || + section->domains_str[i] == '\0' || + section->domains_str[i] == ',' || + section->domains_str[i] == '\n' )) { unsigned int domain_len = (i - j); const char *sni_startp = sni_name + sni_len - domain_len; - const char *domain_startp = config.domains_str + j; + const char *domain_startp = section->domains_str + j; if (sni_len >= domain_len && sni_len < 128 && @@ -159,18 +160,18 @@ struct tls_verdict analyze_tls_data( } check_domain: - if (vrd.target_sni == 1 && config.exclude_domains_strlen != 0) { + if (vrd.target_sni == 1 && section->exclude_domains_strlen != 0) { unsigned int j = 0; - for (unsigned int i = 0; i <= config.exclude_domains_strlen; i++) { + for (unsigned int i = 0; i <= section->exclude_domains_strlen; i++) { if ( i > j && - (i == config.exclude_domains_strlen || - config.exclude_domains_str[i] == '\0' || - config.exclude_domains_str[i] == ',' || - config.exclude_domains_str[i] == '\n' )) { + (i == section->exclude_domains_strlen || + section->exclude_domains_str[i] == '\0' || + section->exclude_domains_str[i] == ',' || + section->exclude_domains_str[i] == '\n' )) { unsigned int domain_len = (i - j); const char *sni_startp = sni_name + sni_len - domain_len; - const char *domain_startp = config.exclude_domains_str + j; + const char *domain_startp = section->exclude_domains_str + j; if (sni_len >= domain_len && sni_len < 128 && @@ -203,7 +204,7 @@ out: brute: - if (config.all_domains) { + if (section->all_domains) { vrd.target_sni = 1; vrd.sni_len = 0; vrd.sni_offset = dlen / 2; @@ -211,15 +212,15 @@ brute: } unsigned int j = 0; - for (unsigned int i = 0; i <= config.domains_strlen; i++) { + for (unsigned int i = 0; i <= section->domains_strlen; i++) { if ( i > j && - (i == config.domains_strlen || - config.domains_str[i] == '\0' || - config.domains_str[i] == ',' || - config.domains_str[i] == '\n' )) { + (i == section->domains_strlen || + section->domains_str[i] == '\0' || + section->domains_str[i] == ',' || + section->domains_str[i] == '\n' )) { unsigned int domain_len = (i - j); - const char *domain_startp = config.domains_str + j; + const char *domain_startp = section->domains_str + j; if (domain_len + dlen + 1> MAX_PACKET_SIZE) { continue; diff --git a/tls.h b/tls.h index 9b4c2a2..024a1cc 100644 --- a/tls.h +++ b/tls.h @@ -20,7 +20,7 @@ struct tls_verdict { * Processes the packet and finds TLS Client Hello information inside it. * data pointer points to start of TLS Message (TCP Payload) */ -struct tls_verdict analyze_tls_data(const uint8_t *data, uint32_t dlen); +struct tls_verdict analyze_tls_data(const struct section_config_t *section, const uint8_t *data, uint32_t dlen); /** diff --git a/utils.h b/utils.h index ddae729..d78b7b5 100644 --- a/utils.h +++ b/utils.h @@ -157,34 +157,34 @@ int seqovl_packet(uint8_t *payload, uint32_t *plen, uint32_t seq_delta); -static inline struct failing_strategy args_default_failing_strategy(void) { +static inline struct failing_strategy args_default_failing_strategy(const struct section_config_t *section) { struct failing_strategy fl_strat = { - .strategy = (unsigned int)config.faking_strategy, - .faking_ttl = config.faking_ttl, - .randseq_offset = (uint32_t)config.fakeseq_offset + .strategy = (unsigned int)section->faking_strategy, + .faking_ttl = section->faking_ttl, + .randseq_offset = (uint32_t)section->fakeseq_offset }; return fl_strat; } -static inline struct fake_type args_default_fake_type(void) { +static inline struct fake_type args_default_fake_type(const struct section_config_t *section) { struct fake_type f_type = { - .sequence_len = config.fake_sni_seq_len, - .strategy = args_default_failing_strategy(), + .sequence_len = section->fake_sni_seq_len, + .strategy = args_default_failing_strategy(section), }; - switch (config.fake_sni_type) { + switch (section->fake_sni_type) { case FAKE_PAYLOAD_RANDOM: f_type.type = FAKE_PAYLOAD_RANDOM; break; case FAKE_PAYLOAD_CUSTOM: f_type.type = FAKE_PAYLOAD_CUSTOM; - f_type.fake_data = config.fake_custom_pkt; - f_type.fake_len = config.fake_custom_pkt_sz; + f_type.fake_data = section->fake_custom_pkt; + f_type.fake_len = section->fake_custom_pkt_sz; break; default: f_type.type = FAKE_PAYLOAD_CUSTOM; - f_type.fake_data = config.fake_sni_pkt; - f_type.fake_len = config.fake_sni_pkt_sz; + f_type.fake_data = section->fake_sni_pkt; + f_type.fake_len = section->fake_sni_pkt_sz; } return f_type; diff --git a/youtubeUnblock.c b/youtubeUnblock.c index 086dbaf..6e4ee5c 100644 --- a/youtubeUnblock.c +++ b/youtubeUnblock.c @@ -264,27 +264,11 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) { uint8_t buff2[MNL_SOCKET_BUFFER_SIZE]; uint32_t buff2_size = MNL_SOCKET_BUFFER_SIZE; - switch (config.fragmentation_strategy) { - case FRAG_STRAT_TCP: - if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128, - buff1, &buff1_size, buff2, &buff2_size)) < 0) { + if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128, + buff1, &buff1_size, buff2, &buff2_size)) < 0) { - errno = -ret; - return ret; - } - break; - case FRAG_STRAT_IP: - if ((ret = ip4_frag(pkt, pktlen, AVAILABLE_MTU-128, - buff1, &buff1_size, buff2, &buff2_size)) < 0) { - - errno = -ret; - return ret; - } - break; - default: - errno = EINVAL; - printf("send_raw_socket: Packet is too big but fragmentation is disabled!\n"); - return -EINVAL; + errno = -ret; + return ret; } int sent = 0;