Add multiple sections with config sets for various domains

This commit is contained in:
Vadim Vetrov 2024-10-13 23:31:26 +03:00
parent 58f4802f64
commit 4c7b63fa7f
No known key found for this signature in database
GPG Key ID: E8A308689D7A73A5
11 changed files with 450 additions and 413 deletions

View File

@ -231,6 +231,8 @@ Available flags:
- `--packet-mark=<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`.

403
args.c
View File

@ -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");
}
@ -525,17 +492,87 @@ void print_welcome() {
printf("IPv6 is disabled\n");
}
if (config.quic_drop) {
printf("All QUIC packets will be dropped\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.sni_detection == SNI_DETECTION_BRUTE) {
printf("Server Name Extension will be parsed in the bruteforce mode\n");
}
ITER_CONFIG_SECTIONS(section) {
int section_number = CONFIG_SECTION_NUMBER(section);
printf("Section #%d\n", section_number);
if (config.all_domains) {
printf("All Client Hello will be targetted by youtubeUnblock!\n");
}
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);
}
}
}

View File

@ -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

113
kargs.c
View File

@ -4,11 +4,11 @@
#include <linux/moduleparam.h>
#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);

View File

@ -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;

157
mangle.c
View File

@ -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;
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;
if (transport_proto == IPPROTO_TCP)
lgtrace_addp("TCP");
else if (transport_proto == IPPROTO_UDP)
lgtrace_addp("UDP");
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:
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:

View File

@ -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 */

45
tls.c
View File

@ -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;

2
tls.h
View File

@ -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);
/**

24
utils.h
View File

@ -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;

View File

@ -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;