mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2024-12-21 22:05:56 +00:00
Add multiple sections with config sets for various domains
This commit is contained in:
parent
58f4802f64
commit
4c7b63fa7f
@ -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.
|
- `--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
|
## 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`.
|
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`.
|
||||||
|
407
args.c
407
args.c
@ -12,8 +12,7 @@
|
|||||||
|
|
||||||
static char custom_fake_buf[MAX_FAKE_SIZE];
|
static char custom_fake_buf[MAX_FAKE_SIZE];
|
||||||
|
|
||||||
struct config_t config = {
|
static const struct section_config_t default_section_config = {
|
||||||
.threads = THREADS_NUM,
|
|
||||||
.frag_sni_reverse = 1,
|
.frag_sni_reverse = 1,
|
||||||
.frag_sni_faked = 0,
|
.frag_sni_faked = 0,
|
||||||
.fragmentation_strategy = FRAGMENTATION_STRATEGY,
|
.fragmentation_strategy = FRAGMENTATION_STRATEGY,
|
||||||
@ -24,31 +23,12 @@ struct config_t config = {
|
|||||||
.fake_sni_type = FAKE_PAYLOAD_DEFAULT,
|
.fake_sni_type = FAKE_PAYLOAD_DEFAULT,
|
||||||
.frag_middle_sni = 1,
|
.frag_middle_sni = 1,
|
||||||
.frag_sni_pos = 1,
|
.frag_sni_pos = 1,
|
||||||
.use_ipv6 = 1,
|
|
||||||
.fakeseq_offset = 10000,
|
.fakeseq_offset = 10000,
|
||||||
.mark = DEFAULT_RAWSOCKET_MARK,
|
|
||||||
.synfake = 0,
|
.synfake = 0,
|
||||||
.synfake_len = 0,
|
.synfake_len = 0,
|
||||||
|
.quic_drop = 0,
|
||||||
|
|
||||||
.sni_detection = SNI_DETECTION_PARSE,
|
|
||||||
|
|
||||||
#ifdef SEG2_DELAY
|
|
||||||
.seg2_delay = SEG2_DELAY,
|
|
||||||
#else
|
|
||||||
.seg2_delay = 0,
|
.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_str = defaul_snistr,
|
||||||
.domains_strlen = sizeof(defaul_snistr),
|
.domains_strlen = sizeof(defaul_snistr),
|
||||||
@ -56,11 +36,25 @@ struct config_t config = {
|
|||||||
.exclude_domains_str = "",
|
.exclude_domains_str = "",
|
||||||
.exclude_domains_strlen = 0,
|
.exclude_domains_strlen = 0,
|
||||||
|
|
||||||
.queue_start_num = DEFAULT_QUEUE_NUM,
|
|
||||||
.fake_sni_pkt = fake_sni_old,
|
.fake_sni_pkt = fake_sni_old,
|
||||||
.fake_sni_pkt_sz = sizeof(fake_sni_old) - 1, // - 1 for null-terminator
|
.fake_sni_pkt_sz = sizeof(fake_sni_old) - 1, // - 1 for null-terminator
|
||||||
.fake_custom_pkt = custom_fake_buf,
|
.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
|
#define OPT_SNI_DOMAINS 1
|
||||||
@ -71,6 +65,8 @@ struct config_t config = {
|
|||||||
#define OPT_FAKE_SNI_SEQ_LEN 11
|
#define OPT_FAKE_SNI_SEQ_LEN 11
|
||||||
#define OPT_FAKE_SNI_TYPE 27
|
#define OPT_FAKE_SNI_TYPE 27
|
||||||
#define OPT_FAKE_CUSTOM_PAYLOAD 28
|
#define OPT_FAKE_CUSTOM_PAYLOAD 28
|
||||||
|
#define OPT_START_SECTION 29
|
||||||
|
#define OPT_END_SECTION 30
|
||||||
#define OPT_FRAG 4
|
#define OPT_FRAG 4
|
||||||
#define OPT_FRAG_SNI_REVERSE 12
|
#define OPT_FRAG_SNI_REVERSE 12
|
||||||
#define OPT_FRAG_SNI_FAKED 13
|
#define OPT_FRAG_SNI_FAKED 13
|
||||||
@ -91,7 +87,7 @@ struct config_t config = {
|
|||||||
#define OPT_NO_GSO 8
|
#define OPT_NO_GSO 8
|
||||||
#define OPT_QUEUE_NUM 9
|
#define OPT_QUEUE_NUM 9
|
||||||
|
|
||||||
#define OPT_MAX OPT_FAKE_CUSTOM_PAYLOAD
|
#define OPT_MAX OPT_END_SECTION
|
||||||
|
|
||||||
static struct option long_opt[] = {
|
static struct option long_opt[] = {
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
@ -123,6 +119,8 @@ static struct option long_opt[] = {
|
|||||||
{"no-ipv6", 0, 0, OPT_NO_IPV6},
|
{"no-ipv6", 0, 0, OPT_NO_IPV6},
|
||||||
{"queue-num", 1, 0, OPT_QUEUE_NUM},
|
{"queue-num", 1, 0, OPT_QUEUE_NUM},
|
||||||
{"packet-mark", 1, 0, OPT_PACKET_MARK},
|
{"packet-mark", 1, 0, OPT_PACKET_MARK},
|
||||||
|
{"fbegin", 0, 0, OPT_START_SECTION},
|
||||||
|
{"fend", 0, 0, OPT_END_SECTION},
|
||||||
{0,0,0,0}
|
{0,0,0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -182,16 +180,27 @@ void print_usage(const char *argv0) {
|
|||||||
printf("\t--trace\n");
|
printf("\t--trace\n");
|
||||||
printf("\t--no-gso\n");
|
printf("\t--no-gso\n");
|
||||||
printf("\t--no-ipv6\n");
|
printf("\t--no-ipv6\n");
|
||||||
|
printf("\t--fbegin\n");
|
||||||
|
printf("\t--fend\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_args(int argc, char *argv[]) {
|
int parse_args(int argc, char *argv[]) {
|
||||||
int opt;
|
int opt;
|
||||||
int optIdx;
|
int optIdx = 0;
|
||||||
long num;
|
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) {
|
while ((opt = getopt_long(argc, argv, "hv", long_opt, &optIdx)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
/* config_t scoped configs */
|
||||||
case 'h':
|
case 'h':
|
||||||
print_usage(argv[0]);
|
print_usage(argv[0]);
|
||||||
goto stop_exec;
|
goto stop_exec;
|
||||||
@ -199,49 +208,98 @@ int parse_args(int argc, char *argv[]) {
|
|||||||
print_version();
|
print_version();
|
||||||
goto stop_exec;
|
goto stop_exec;
|
||||||
case OPT_TRACE:
|
case OPT_TRACE:
|
||||||
|
if (section_iter != SECT_ITER_DEFAULT)
|
||||||
|
goto invalid_opt;
|
||||||
config.verbose = 2;
|
config.verbose = 2;
|
||||||
break;
|
break;
|
||||||
case OPT_SILENT:
|
case OPT_SILENT:
|
||||||
|
if (section_iter != SECT_ITER_DEFAULT)
|
||||||
|
goto invalid_opt;
|
||||||
|
|
||||||
config.verbose = 0;
|
config.verbose = 0;
|
||||||
break;
|
break;
|
||||||
case OPT_NO_GSO:
|
case OPT_NO_GSO:
|
||||||
|
if (section_iter != SECT_ITER_DEFAULT)
|
||||||
|
goto invalid_opt;
|
||||||
|
|
||||||
config.use_gso = 0;
|
config.use_gso = 0;
|
||||||
break;
|
break;
|
||||||
case OPT_NO_IPV6:
|
case OPT_NO_IPV6:
|
||||||
|
if (section_iter != SECT_ITER_DEFAULT)
|
||||||
|
goto invalid_opt;
|
||||||
|
|
||||||
config.use_ipv6 = 0;
|
config.use_ipv6 = 0;
|
||||||
break;
|
break;
|
||||||
case OPT_QUIC_DROP:
|
case OPT_THREADS:
|
||||||
config.quic_drop = 1;
|
if (section_iter != SECT_ITER_DEFAULT)
|
||||||
break;
|
goto invalid_opt;
|
||||||
case OPT_SNI_DOMAINS:
|
|
||||||
if (!strcmp(optarg, "all")) {
|
|
||||||
config.all_domains = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
config.domains_str = optarg;
|
num = parse_numeric_option(optarg);
|
||||||
config.domains_strlen = strlen(config.domains_str);
|
if (errno != 0 || num < 0 || num > MAX_THREADS) {
|
||||||
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 {
|
|
||||||
goto invalid_opt;
|
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;
|
break;
|
||||||
case OPT_FRAG:
|
case OPT_FRAG:
|
||||||
if (strcmp(optarg, "tcp") == 0) {
|
if (strcmp(optarg, "tcp") == 0) {
|
||||||
config.fragmentation_strategy = FRAG_STRAT_TCP;
|
sect_config->fragmentation_strategy = FRAG_STRAT_TCP;
|
||||||
} else if (strcmp(optarg, "ip") == 0) {
|
} 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) {
|
} else if (strcmp(optarg, "none") == 0) {
|
||||||
config.fragmentation_strategy = FRAG_STRAT_NONE;
|
sect_config->fragmentation_strategy = FRAG_STRAT_NONE;
|
||||||
} else {
|
} else {
|
||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
@ -249,9 +307,9 @@ int parse_args(int argc, char *argv[]) {
|
|||||||
break;
|
break;
|
||||||
case OPT_FRAG_SNI_FAKED:
|
case OPT_FRAG_SNI_FAKED:
|
||||||
if (strcmp(optarg, "1") == 0) {
|
if (strcmp(optarg, "1") == 0) {
|
||||||
config.frag_sni_faked = 1;
|
sect_config->frag_sni_faked = 1;
|
||||||
} else if (strcmp(optarg, "0") == 0) {
|
} else if (strcmp(optarg, "0") == 0) {
|
||||||
config.frag_sni_faked = 0;
|
sect_config->frag_sni_faked = 0;
|
||||||
} else {
|
} else {
|
||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
@ -259,9 +317,9 @@ int parse_args(int argc, char *argv[]) {
|
|||||||
break;
|
break;
|
||||||
case OPT_FRAG_SNI_REVERSE:
|
case OPT_FRAG_SNI_REVERSE:
|
||||||
if (strcmp(optarg, "1") == 0) {
|
if (strcmp(optarg, "1") == 0) {
|
||||||
config.frag_sni_reverse = 1;
|
sect_config->frag_sni_reverse = 1;
|
||||||
} else if (strcmp(optarg, "0") == 0) {
|
} else if (strcmp(optarg, "0") == 0) {
|
||||||
config.frag_sni_reverse = 0;
|
sect_config->frag_sni_reverse = 0;
|
||||||
} else {
|
} else {
|
||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
@ -269,9 +327,9 @@ int parse_args(int argc, char *argv[]) {
|
|||||||
break;
|
break;
|
||||||
case OPT_FRAG_MIDDLE_SNI:
|
case OPT_FRAG_MIDDLE_SNI:
|
||||||
if (strcmp(optarg, "1") == 0) {
|
if (strcmp(optarg, "1") == 0) {
|
||||||
config.frag_middle_sni = 1;
|
sect_config->frag_middle_sni = 1;
|
||||||
} else if (strcmp(optarg, "0") == 0) {
|
} else if (strcmp(optarg, "0") == 0) {
|
||||||
config.frag_middle_sni = 0;
|
sect_config->frag_middle_sni = 0;
|
||||||
} else {
|
} else {
|
||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
@ -283,19 +341,19 @@ int parse_args(int argc, char *argv[]) {
|
|||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.frag_sni_pos = num;
|
sect_config->frag_sni_pos = num;
|
||||||
break;
|
break;
|
||||||
case OPT_FAKING_STRATEGY:
|
case OPT_FAKING_STRATEGY:
|
||||||
if (strcmp(optarg, "randseq") == 0) {
|
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) {
|
} 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) {
|
} 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) {
|
} 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) {
|
} else if (strcmp(optarg, "md5sum") == 0) {
|
||||||
config.faking_strategy = FAKE_STRAT_TCP_MD5SUM;
|
sect_config->faking_strategy = FAKE_STRAT_TCP_MD5SUM;
|
||||||
} else {
|
} else {
|
||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
@ -307,7 +365,7 @@ int parse_args(int argc, char *argv[]) {
|
|||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.faking_ttl = num;
|
sect_config->faking_ttl = num;
|
||||||
break;
|
break;
|
||||||
case OPT_FAKE_SEQ_OFFSET:
|
case OPT_FAKE_SEQ_OFFSET:
|
||||||
num = parse_numeric_option(optarg);
|
num = parse_numeric_option(optarg);
|
||||||
@ -315,13 +373,13 @@ int parse_args(int argc, char *argv[]) {
|
|||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.fakeseq_offset = num;
|
sect_config->fakeseq_offset = num;
|
||||||
break;
|
break;
|
||||||
case OPT_FAKE_SNI:
|
case OPT_FAKE_SNI:
|
||||||
if (strcmp(optarg, "1") == 0) {
|
if (strcmp(optarg, "1") == 0) {
|
||||||
config.fake_sni = 1;
|
sect_config->fake_sni = 1;
|
||||||
} else if (strcmp(optarg, "0") == 0) {
|
} else if (strcmp(optarg, "0") == 0) {
|
||||||
config.fake_sni = 0;
|
sect_config->fake_sni = 0;
|
||||||
} else {
|
} else {
|
||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
@ -333,15 +391,15 @@ int parse_args(int argc, char *argv[]) {
|
|||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.fake_sni_seq_len = num;
|
sect_config->fake_sni_seq_len = num;
|
||||||
break;
|
break;
|
||||||
case OPT_FAKE_SNI_TYPE:
|
case OPT_FAKE_SNI_TYPE:
|
||||||
if (strcmp(optarg, "default") == 0) {
|
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) {
|
} 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) {
|
} else if (strcmp(optarg, "custom") == 0) {
|
||||||
config.fake_sni_type = FAKE_PAYLOAD_CUSTOM;
|
sect_config->fake_sni_type = FAKE_PAYLOAD_CUSTOM;
|
||||||
} else {
|
} else {
|
||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
@ -368,8 +426,8 @@ int parse_args(int argc, char *argv[]) {
|
|||||||
sscanf(custom_hex_fake + (i << 1), "%2hhx", custom_buf + i);
|
sscanf(custom_hex_fake + (i << 1), "%2hhx", custom_buf + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.fake_custom_pkt_sz = custom_len;
|
sect_config->fake_custom_pkt_sz = custom_len;
|
||||||
config.fake_custom_pkt = (char *)custom_buf;
|
sect_config->fake_custom_pkt = (char *)custom_buf;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_FK_WINSIZE:
|
case OPT_FK_WINSIZE:
|
||||||
@ -378,66 +436,37 @@ int parse_args(int argc, char *argv[]) {
|
|||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.fk_winsize = num;
|
sect_config->fk_winsize = num;
|
||||||
break;
|
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:
|
case OPT_SEG2DELAY:
|
||||||
num = parse_numeric_option(optarg);
|
num = parse_numeric_option(optarg);
|
||||||
if (errno != 0 || num < 0) {
|
if (errno != 0 || num < 0) {
|
||||||
goto invalid_opt;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.seg2_delay = num;
|
sect_config->seg2_delay = num;
|
||||||
break;
|
break;
|
||||||
case OPT_THREADS:
|
case OPT_QUIC_DROP:
|
||||||
num = parse_numeric_option(optarg);
|
sect_config->quic_drop = 1;
|
||||||
if (errno != 0 || num < 0 || num > MAX_THREADS) {
|
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;
|
goto invalid_opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.threads = num;
|
|
||||||
break;
|
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:
|
default:
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// out:
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
return 0;
|
return 0;
|
||||||
stop_exec:
|
stop_exec:
|
||||||
@ -453,68 +482,6 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void print_welcome() {
|
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) {
|
if (config.use_gso) {
|
||||||
printf("GSO is enabled\n");
|
printf("GSO is enabled\n");
|
||||||
}
|
}
|
||||||
@ -524,18 +491,88 @@ void print_welcome() {
|
|||||||
} else {
|
} else {
|
||||||
printf("IPv6 is disabled\n");
|
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) {
|
ITER_CONFIG_SECTIONS(section) {
|
||||||
printf("All QUIC packets will be dropped\n");
|
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
54
config.h
54
config.h
@ -18,11 +18,10 @@ struct instance_config_t {
|
|||||||
};
|
};
|
||||||
extern struct instance_config_t instance_config;
|
extern struct instance_config_t instance_config;
|
||||||
|
|
||||||
struct config_t {
|
struct section_config_t {
|
||||||
unsigned int queue_start_num;
|
const char *domains_str;
|
||||||
int threads;
|
unsigned int domains_strlen;
|
||||||
int use_gso;
|
|
||||||
int use_ipv6;
|
|
||||||
int fragmentation_strategy;
|
int fragmentation_strategy;
|
||||||
int frag_sni_reverse;
|
int frag_sni_reverse;
|
||||||
int frag_sni_faked;
|
int frag_sni_faked;
|
||||||
@ -39,18 +38,13 @@ struct config_t {
|
|||||||
#define FAKE_PAYLOAD_DEFAULT 2
|
#define FAKE_PAYLOAD_DEFAULT 2
|
||||||
int fake_sni_type;
|
int fake_sni_type;
|
||||||
|
|
||||||
#define VERBOSE_INFO 0
|
|
||||||
#define VERBOSE_DEBUG 1
|
|
||||||
#define VERBOSE_TRACE 2
|
|
||||||
int verbose;
|
|
||||||
int quic_drop;
|
int quic_drop;
|
||||||
#define SNI_DETECTION_PARSE 0
|
|
||||||
#define SNI_DETECTION_BRUTE 1
|
|
||||||
int sni_detection;
|
|
||||||
/* In milliseconds */
|
/* In milliseconds */
|
||||||
unsigned int seg2_delay;
|
unsigned int seg2_delay;
|
||||||
const char *domains_str;
|
int synfake;
|
||||||
unsigned int domains_strlen;
|
unsigned int synfake_len;
|
||||||
|
|
||||||
const char *exclude_domains_str;
|
const char *exclude_domains_str;
|
||||||
unsigned int exclude_domains_strlen;
|
unsigned int exclude_domains_strlen;
|
||||||
unsigned int all_domains;
|
unsigned int all_domains;
|
||||||
@ -61,16 +55,42 @@ struct config_t {
|
|||||||
const char *fake_custom_pkt;
|
const char *fake_custom_pkt;
|
||||||
unsigned int fake_custom_pkt_sz;
|
unsigned int fake_custom_pkt_sz;
|
||||||
|
|
||||||
|
|
||||||
unsigned int fk_winsize;
|
unsigned int fk_winsize;
|
||||||
int fakeseq_offset;
|
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;
|
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;
|
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
|
#define MAX_THREADS 16
|
||||||
|
|
||||||
#ifndef THREADS_NUM
|
#ifndef THREADS_NUM
|
||||||
|
113
kargs.c
113
kargs.c
@ -4,11 +4,11 @@
|
|||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
static char custom_fake_buf[MAX_FAKE_SIZE];
|
|
||||||
|
|
||||||
#define STR_MAXLEN 2048
|
#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_reverse = 1,
|
||||||
.frag_sni_faked = 0,
|
.frag_sni_faked = 0,
|
||||||
.fragmentation_strategy = FRAGMENTATION_STRATEGY,
|
.fragmentation_strategy = FRAGMENTATION_STRATEGY,
|
||||||
@ -16,45 +16,44 @@ struct config_t config = {
|
|||||||
.faking_ttl = FAKE_TTL,
|
.faking_ttl = FAKE_TTL,
|
||||||
.fake_sni = 1,
|
.fake_sni = 1,
|
||||||
.fake_sni_seq_len = 1,
|
.fake_sni_seq_len = 1,
|
||||||
|
.fake_sni_type = FAKE_PAYLOAD_DEFAULT,
|
||||||
.frag_middle_sni = 1,
|
.frag_middle_sni = 1,
|
||||||
.frag_sni_pos = 1,
|
.frag_sni_pos = 1,
|
||||||
.use_ipv6 = 1,
|
|
||||||
.fakeseq_offset = 10000,
|
.fakeseq_offset = 10000,
|
||||||
.mark = DEFAULT_RAWSOCKET_MARK,
|
|
||||||
.synfake = 0,
|
.synfake = 0,
|
||||||
.synfake_len = 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,
|
.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_str = defaul_snistr,
|
||||||
.domains_strlen = sizeof(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 = fake_sni_old,
|
||||||
.fake_sni_pkt_sz = sizeof(fake_sni_old) - 1, // - 1 for null-terminator
|
.fake_sni_pkt_sz = sizeof(fake_sni_old) - 1, // - 1 for null-terminator
|
||||||
.fake_custom_pkt = custom_fake_buf,
|
.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) {
|
static int unumeric_set(const char *val, const struct kernel_param *kp) {
|
||||||
int n = 0, ret;
|
int n = 0, ret;
|
||||||
ret = kstrtoint(val, 10, &n);
|
ret = kstrtoint(val, 10, &n);
|
||||||
@ -113,19 +112,19 @@ static const struct kernel_param_ops inverse_boolean_ops = {
|
|||||||
.get = inverse_boolean_get,
|
.get = inverse_boolean_get,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_param_cb(fake_sni, &boolean_parameter_ops, &config.fake_sni, 0664);
|
module_param_cb(fake_sni, &boolean_parameter_ops, &def_section->fake_sni, 0664);
|
||||||
module_param_cb(fake_sni_seq_len, &unumeric_parameter_ops, &config.fake_sni_seq_len, 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, &config.faking_ttl, 0664);
|
module_param_cb(faking_ttl, &unumeric_parameter_ops, &def_section->faking_ttl, 0664);
|
||||||
module_param_cb(fake_seq_offset, &unumeric_parameter_ops, &config.fakeseq_offset, 0664);
|
module_param_cb(fake_seq_offset, &unumeric_parameter_ops, &def_section->fakeseq_offset, 0664);
|
||||||
module_param_cb(frag_sni_reverse, &unumeric_parameter_ops, &config.frag_sni_reverse, 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, &config.frag_sni_faked, 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, &config.frag_middle_sni, 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, &config.frag_sni_pos, 0664);
|
module_param_cb(frag_sni_pos, &unumeric_parameter_ops, &def_section->frag_sni_pos, 0664);
|
||||||
module_param_cb(fk_winsize, &unumeric_parameter_ops, &config.fk_winsize, 0664);
|
module_param_cb(fk_winsize, &unumeric_parameter_ops, &def_section->fk_winsize, 0664);
|
||||||
module_param_cb(synfake, &boolean_parameter_ops, &config.synfake, 0664);
|
module_param_cb(synfake, &boolean_parameter_ops, &def_section->synfake, 0664);
|
||||||
module_param_cb(synfake_len, &unumeric_parameter_ops, &config.synfake_len, 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(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) {
|
static int sni_domains_set(const char *val, const struct kernel_param *kp) {
|
||||||
size_t len;
|
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);
|
ret = param_set_charp(val, kp);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
config.domains_strlen = 0;
|
def_section->domains_strlen = 0;
|
||||||
} else {
|
} else {
|
||||||
config.domains_strlen = len;
|
def_section->domains_strlen = len;
|
||||||
if (len == 3 && !strncmp(val, "all", len)) {
|
if (len == 3 && !strncmp(val, "all", len)) {
|
||||||
config.all_domains = 1;
|
def_section->all_domains = 1;
|
||||||
} else {
|
} 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,
|
.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) {
|
static int exclude_domains_set(const char *val, const struct kernel_param *kp) {
|
||||||
size_t len;
|
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);
|
ret = param_set_charp(val, kp);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
config.exclude_domains_strlen = 0;
|
def_section->exclude_domains_strlen = 0;
|
||||||
} else {
|
} else {
|
||||||
config.exclude_domains_strlen = len;
|
def_section->exclude_domains_strlen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -191,10 +190,10 @@ static const struct kernel_param_ops exclude_domains_ops = {
|
|||||||
.get = param_get_charp,
|
.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(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) {
|
static int verbosity_set(const char *val, const struct kernel_param *kp) {
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -297,7 +296,7 @@ static const struct kernel_param_ops frag_strat_ops = {
|
|||||||
.get = frag_strat_get,
|
.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) {
|
static int fake_strat_set(const char *val, const struct kernel_param *kp) {
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -358,7 +357,7 @@ static const struct kernel_param_ops fake_strat_ops = {
|
|||||||
.get = fake_strat_get,
|
.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) {
|
static int sni_detection_set(const char *val, const struct kernel_param *kp) {
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -404,7 +403,7 @@ static const struct kernel_param_ops sni_detection_ops = {
|
|||||||
.get = sni_detection_get,
|
.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) {
|
static int fake_type_set(const char *val, const struct kernel_param *kp) {
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -455,7 +454,7 @@ static const struct kernel_param_ops fake_type_ops = {
|
|||||||
.get = fake_type_get,
|
.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) {
|
static int fake_custom_pl_set(const char *val, const struct kernel_param *kp) {
|
||||||
size_t len;
|
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);
|
sscanf(custom_hex_fake + (i << 1), "%2hhx", custom_buf + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.fake_custom_pkt_sz = custom_len;
|
def_section->fake_custom_pkt_sz = custom_len;
|
||||||
config.fake_custom_pkt = (char *)custom_buf;
|
def_section->fake_custom_pkt = (char *)custom_buf;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fake_custom_pl_get(char *buffer, const struct kernel_param *kp) {
|
static int fake_custom_pl_get(char *buffer, const struct kernel_param *kp) {
|
||||||
int cflen = config.fake_custom_pkt_sz;
|
int cflen = def_section->fake_custom_pkt_sz;
|
||||||
const uint8_t *cbf_data = config.fake_custom_pkt;
|
const uint8_t *cbf_data = def_section->fake_custom_pkt;
|
||||||
int bflen = config.fake_custom_pkt_sz << 1;
|
int bflen = def_section->fake_custom_pkt_sz << 1;
|
||||||
|
|
||||||
for (int i = 0; i < cflen; i++) {
|
for (int i = 0; i < cflen; i++) {
|
||||||
sprintf(buffer + (i << 1), "%02x", *((unsigned char *)cbf_data + 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,
|
.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);
|
||||||
|
21
kytunblock.c
21
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 buff1_size = MAX_PACKET_SIZE;
|
||||||
uint32_t buff2_size = MAX_PACKET_SIZE;
|
uint32_t buff2_size = MAX_PACKET_SIZE;
|
||||||
|
|
||||||
switch (config.fragmentation_strategy) {
|
if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
||||||
case FRAG_STRAT_TCP:
|
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;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
|
161
mangle.c
161
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 ipver = netproto_version(raw_payload, raw_payload_len);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
lgtrace_start();
|
||||||
|
lgtrace_addp("IPv%d", ipver);
|
||||||
|
|
||||||
if (ipver == IP4VERSION) {
|
if (ipver == IP4VERSION) {
|
||||||
ret = ip4_payload_split((uint8_t *)raw_payload, raw_payload_len,
|
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;
|
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) {
|
ITER_CONFIG_SECTIONS(section) {
|
||||||
case IPPROTO_TCP:
|
lgtrace_addp("Section #%d", CONFIG_SECTION_NUMBER(section));
|
||||||
return process_tcp_packet(raw_payload, raw_payload_len);
|
|
||||||
case IPPROTO_UDP:
|
switch (transport_proto) {
|
||||||
return process_udp_packet(raw_payload, raw_payload_len);
|
case IPPROTO_TCP:
|
||||||
default:
|
verdict = process_tcp_packet(section, raw_payload, raw_payload_len);
|
||||||
goto accept;
|
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;
|
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;
|
const void *ipxh;
|
||||||
uint32_t iph_len;
|
uint32_t iph_len;
|
||||||
const struct tcphdr *tcph;
|
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);
|
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,
|
int ret = tcp_payload_split((uint8_t *)raw_payload, raw_payload_len,
|
||||||
(void *)&ipxh, &iph_len,
|
(void *)&ipxh, &iph_len,
|
||||||
(struct tcphdr **)&tcph, &tcph_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;
|
goto accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcph->syn && config.synfake) {
|
if (tcph->syn && section->synfake) {
|
||||||
lgtrace_addp("TCP syn alter");
|
lgtrace_addp("TCP syn alter");
|
||||||
|
|
||||||
NETBUF_ALLOC(payload, MAX_PACKET_SIZE);
|
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, ipxh, iph_len);
|
||||||
memcpy(payload + iph_len, tcph, tcph_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)
|
if (section->synfake_len)
|
||||||
fake_len = min(config.synfake_len, fake_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);
|
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);
|
NETBUF_FREE(payload);
|
||||||
goto accept;
|
goto accept;
|
||||||
}
|
}
|
||||||
lgtrace_addp("rawsocket sent %d", ret);
|
|
||||||
|
|
||||||
NETBUF_FREE(payload);
|
NETBUF_FREE(payload);
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcph->syn) goto accept;
|
if (tcph->syn) goto continue_flow;
|
||||||
|
|
||||||
struct tls_verdict vrd = analyze_tls_data(data, dlen);
|
struct tls_verdict vrd = analyze_tls_data(section, data, dlen);
|
||||||
lgtrace_addp("Analyzed");
|
lgtrace_addp("TLS analyzed");
|
||||||
|
|
||||||
if (vrd.sni_len != 0) {
|
if (vrd.sni_len != 0) {
|
||||||
lgtrace_addp("SNI detected: %.*s", vrd.sni_len, data + vrd.sni_offset);
|
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;
|
goto accept_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.fk_winsize) {
|
if (section->fk_winsize) {
|
||||||
tcph->window = htons(config.fk_winsize);
|
tcph->window = htons(section->fk_winsize);
|
||||||
set_tcp_checksum(tcph, iph, iph_len);
|
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!");
|
lgdebugmsg("WARNING! Client Hello packet is too big and may cause issues!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.fake_sni) {
|
if (section->fake_sni) {
|
||||||
post_fake_sni(args_default_fake_type(), iph, iph_len, tcph, tcph_len);
|
post_fake_sni(args_default_fake_type(section), iph, iph_len, tcph, tcph_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ipd_offset;
|
size_t ipd_offset;
|
||||||
size_t mid_offset;
|
size_t mid_offset;
|
||||||
|
|
||||||
switch (config.fragmentation_strategy) {
|
switch (section->fragmentation_strategy) {
|
||||||
case FRAG_STRAT_TCP: {
|
case FRAG_STRAT_TCP: {
|
||||||
ipd_offset = vrd.sni_target_offset;
|
ipd_offset = vrd.sni_target_offset;
|
||||||
mid_offset = ipd_offset + vrd.sni_target_len / 2;
|
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];
|
uint32_t poses[2];
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
if (config.frag_sni_pos && dlen > config.frag_sni_pos) {
|
if (section->frag_sni_pos && dlen > section->frag_sni_pos) {
|
||||||
poses[cnt++] = config.frag_sni_pos;
|
poses[cnt++] = section->frag_sni_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.frag_middle_sni) {
|
if (section->frag_middle_sni) {
|
||||||
poses[cnt++] = mid_offset;
|
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;
|
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) {
|
if (ret < 0) {
|
||||||
lgerror("tcp4 send frags", ret);
|
lgerror("tcp4 send frags", ret);
|
||||||
goto accept_lc;
|
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];
|
uint32_t poses[2];
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
if (config.frag_sni_pos && dlen > config.frag_sni_pos) {
|
if (section->frag_sni_pos && dlen > section->frag_sni_pos) {
|
||||||
poses[cnt] = config.frag_sni_pos + ((char *)data - (char *)tcph);
|
poses[cnt] = section->frag_sni_pos + ((char *)data - (char *)tcph);
|
||||||
poses[cnt] += 8 - poses[cnt] % 8;
|
poses[cnt] += 8 - poses[cnt] % 8;
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.frag_middle_sni) {
|
if (section->frag_middle_sni) {
|
||||||
poses[cnt++] = mid_offset;
|
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;
|
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) {
|
if (ret < 0) {
|
||||||
lgerror("ip4 send frags", ret);
|
lgerror("ip4 send frags", ret);
|
||||||
goto accept_lc;
|
goto accept_lc;
|
||||||
@ -292,27 +308,24 @@ drop_lc:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue_flow:
|
||||||
|
lgtrace_addp("continue_flow");
|
||||||
|
return PKT_CONTINUE;
|
||||||
accept:
|
accept:
|
||||||
lgtrace_addp("accept");
|
lgtrace_addp("accept");
|
||||||
lgtrace_end();
|
|
||||||
|
|
||||||
return PKT_ACCEPT;
|
return PKT_ACCEPT;
|
||||||
drop:
|
drop:
|
||||||
lgtrace_addp("drop");
|
lgtrace_addp("drop");
|
||||||
lgtrace_end();
|
|
||||||
|
|
||||||
return PKT_DROP;
|
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;
|
const void *iph;
|
||||||
uint32_t iph_len;
|
uint32_t iph_len;
|
||||||
const struct udphdr *udph;
|
const struct udphdr *udph;
|
||||||
const uint8_t *data;
|
const uint8_t *data;
|
||||||
uint32_t dlen;
|
uint32_t dlen;
|
||||||
int ipver = netproto_version(pkt, pktlen);
|
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,
|
int ret = udp_payload_split((uint8_t *)pkt, pktlen,
|
||||||
(void **)&iph, &iph_len,
|
(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");
|
lgtrace_addp("QUIC probe");
|
||||||
const struct quic_lhdr *qch;
|
const struct quic_lhdr *qch;
|
||||||
uint32_t qch_len;
|
uint32_t qch_len;
|
||||||
@ -368,9 +381,6 @@ int process_udp_packet(const uint8_t *pkt, uint32_t pktlen) {
|
|||||||
lgtrace_addp("quic initial message");
|
lgtrace_addp("quic initial message");
|
||||||
}
|
}
|
||||||
|
|
||||||
accept_quic:
|
|
||||||
;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (1) {
|
if (1) {
|
||||||
lgtrace_addp("Probe udp");
|
lgtrace_addp("Probe udp");
|
||||||
@ -402,29 +412,26 @@ accept_quic:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
continue_flow:
|
||||||
|
lgtrace_addp("continue_flow");
|
||||||
|
return PKT_CONTINUE;
|
||||||
|
accept_quic:
|
||||||
accept:
|
accept:
|
||||||
lgtrace_addp("accepted");
|
|
||||||
lgtrace_end();
|
|
||||||
|
|
||||||
return PKT_ACCEPT;
|
return PKT_ACCEPT;
|
||||||
drop:
|
drop:
|
||||||
lgtrace_addp("dropped");
|
|
||||||
lgtrace_end();
|
|
||||||
|
|
||||||
return PKT_DROP;
|
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 (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) {
|
if (!instance_config.send_delayed_packet) {
|
||||||
return -EINVAL;
|
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(
|
instance_config.send_delayed_packet(
|
||||||
packet, pktlen, config.seg2_delay);
|
packet, pktlen, section->seg2_delay);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -479,21 +486,21 @@ int send_ip4_frags(const uint8_t *packet, uint32_t pktlen, const uint32_t *poses
|
|||||||
|
|
||||||
dvs += frag_pos;
|
dvs += frag_pos;
|
||||||
|
|
||||||
if (config.frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto send_frag2;
|
goto send_frag2;
|
||||||
send_frag1:
|
send_frag1:
|
||||||
ret = send_ip4_frags(frag1, f1len, NULL, 0, 0);
|
ret = send_ip4_frags(section, frag1, f1len, NULL, 0, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto out_lc;
|
goto out_lc;
|
||||||
|
|
||||||
send_fake:
|
send_fake:
|
||||||
/*
|
/*
|
||||||
if (config.frag_sni_faked) {
|
if (section->frag_sni_faked) {
|
||||||
ITER_FAKE_STRAT(config.faking_strategy, strategy) {
|
ITER_FAKE_STRAT(section->faking_strategy, strategy) {
|
||||||
uint32_t iphfl;
|
uint32_t iphfl;
|
||||||
fake_pad_len = f2len;
|
fake_pad_len = f2len;
|
||||||
ret = ip4_payload_split(frag2, f2len, NULL, &iphfl, NULL, NULL);
|
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;
|
goto send_frag1;
|
||||||
|
|
||||||
send_frag2:
|
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) {
|
if (ret < 0) {
|
||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto send_fake;
|
goto send_fake;
|
||||||
|
|
||||||
out_lc:
|
out_lc:
|
||||||
@ -545,15 +552,15 @@ out:
|
|||||||
return 0;
|
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 (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) {
|
if (!instance_config.send_delayed_packet) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
instance_config.send_delayed_packet(
|
instance_config.send_delayed_packet(
|
||||||
packet, pktlen, config.seg2_delay);
|
packet, pktlen, section->seg2_delay);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -601,49 +608,49 @@ int send_tcp_frags(const uint8_t *packet, uint32_t pktlen, const uint32_t *poses
|
|||||||
|
|
||||||
dvs += poses[0];
|
dvs += poses[0];
|
||||||
|
|
||||||
if (config.frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto send_frag2;
|
goto send_frag2;
|
||||||
|
|
||||||
send_frag1:
|
send_frag1:
|
||||||
{
|
{
|
||||||
ret = send_tcp_frags(frag1, f1len, NULL, 0, 0);
|
ret = send_tcp_frags(section, frag1, f1len, NULL, 0, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto out_lc;
|
goto out_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
send_fake:
|
send_fake:
|
||||||
if (config.frag_sni_faked) {
|
if (section->frag_sni_faked) {
|
||||||
uint32_t iphfl, tcphfl;
|
uint32_t iphfl, tcphfl;
|
||||||
void *iph;
|
void *iph;
|
||||||
struct tcphdr *tcph;
|
struct tcphdr *tcph;
|
||||||
ret = tcp_payload_split(frag2, f2len, &iph, &iphfl, &tcph, &tcphfl, NULL, NULL);
|
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) {
|
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_PAST_SEQ;
|
||||||
f_type.strategy.strategy |= FAKE_STRAT_RAND_SEQ;
|
f_type.strategy.strategy |= FAKE_STRAT_RAND_SEQ;
|
||||||
f_type.strategy.randseq_offset = dvs;
|
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);
|
post_fake_sni(f_type, iph, iphfl, tcph, tcphfl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto send_frag1;
|
goto send_frag1;
|
||||||
|
|
||||||
send_frag2:
|
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) {
|
if (ret < 0) {
|
||||||
goto erret_lc;
|
goto erret_lc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.frag_sni_reverse)
|
if (section->frag_sni_reverse)
|
||||||
goto send_fake;
|
goto send_fake;
|
||||||
}
|
}
|
||||||
out_lc:
|
out_lc:
|
||||||
|
10
mangle.h
10
mangle.h
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#define PKT_ACCEPT 0
|
#define PKT_ACCEPT 0
|
||||||
#define PKT_DROP 1
|
#define PKT_DROP 1
|
||||||
|
// Used for section config
|
||||||
|
#define PKT_CONTINUE 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes the packet and returns verdict.
|
* 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.
|
* Processe the TCP packet.
|
||||||
* Returns verdict.
|
* 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.
|
* Processes the UDP packet.
|
||||||
* Returns verdict.
|
* 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.
|
* Poses are relative to start of TCP payload.
|
||||||
* dvs used internally and should be zero.
|
* 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 uint8_t *packet, uint32_t pktlen,
|
||||||
const uint32_t *poses, uint32_t poses_len, uint32_t dvs);
|
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.
|
* Poses are relative to start of TCP payload.
|
||||||
* dvs used internally and should be zero.
|
* 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 uint8_t *packet, uint32_t pktlen,
|
||||||
const uint32_t *poses, uint32_t poses_len, uint32_t dvs);
|
const uint32_t *poses, uint32_t poses_len, uint32_t dvs);
|
||||||
#endif /* YU_MANGLE_H */
|
#endif /* YU_MANGLE_H */
|
||||||
|
45
tls.c
45
tls.c
@ -21,6 +21,7 @@
|
|||||||
* dlen Length of `data`.
|
* dlen Length of `data`.
|
||||||
*/
|
*/
|
||||||
struct tls_verdict analyze_tls_data(
|
struct tls_verdict analyze_tls_data(
|
||||||
|
const struct section_config_t *section,
|
||||||
const uint8_t *data,
|
const uint8_t *data,
|
||||||
uint32_t dlen)
|
uint32_t dlen)
|
||||||
{
|
{
|
||||||
@ -43,7 +44,7 @@ struct tls_verdict analyze_tls_data(
|
|||||||
if (tls_content_type != TLS_CONTENT_TYPE_HANDSHAKE)
|
if (tls_content_type != TLS_CONTENT_TYPE_HANDSHAKE)
|
||||||
goto nextMessage;
|
goto nextMessage;
|
||||||
|
|
||||||
if (config.sni_detection == SNI_DETECTION_BRUTE) {
|
if (section->sni_detection == SNI_DETECTION_BRUTE) {
|
||||||
goto brute;
|
goto brute;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,22 +127,22 @@ struct tls_verdict analyze_tls_data(
|
|||||||
vrd.sni_len = sni_len;
|
vrd.sni_len = sni_len;
|
||||||
vrd.sni_target_len = vrd.sni_len;
|
vrd.sni_target_len = vrd.sni_len;
|
||||||
|
|
||||||
if (config.all_domains) {
|
if (section->all_domains) {
|
||||||
vrd.target_sni = 1;
|
vrd.target_sni = 1;
|
||||||
goto check_domain;
|
goto check_domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int j = 0;
|
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 &&
|
if ( i > j &&
|
||||||
(i == config.domains_strlen ||
|
(i == section->domains_strlen ||
|
||||||
config.domains_str[i] == '\0' ||
|
section->domains_str[i] == '\0' ||
|
||||||
config.domains_str[i] == ',' ||
|
section->domains_str[i] == ',' ||
|
||||||
config.domains_str[i] == '\n' )) {
|
section->domains_str[i] == '\n' )) {
|
||||||
|
|
||||||
unsigned int domain_len = (i - j);
|
unsigned int domain_len = (i - j);
|
||||||
const char *sni_startp = sni_name + sni_len - domain_len;
|
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 &&
|
if (sni_len >= domain_len &&
|
||||||
sni_len < 128 &&
|
sni_len < 128 &&
|
||||||
@ -159,18 +160,18 @@ struct tls_verdict analyze_tls_data(
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_domain:
|
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;
|
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 &&
|
if ( i > j &&
|
||||||
(i == config.exclude_domains_strlen ||
|
(i == section->exclude_domains_strlen ||
|
||||||
config.exclude_domains_str[i] == '\0' ||
|
section->exclude_domains_str[i] == '\0' ||
|
||||||
config.exclude_domains_str[i] == ',' ||
|
section->exclude_domains_str[i] == ',' ||
|
||||||
config.exclude_domains_str[i] == '\n' )) {
|
section->exclude_domains_str[i] == '\n' )) {
|
||||||
|
|
||||||
unsigned int domain_len = (i - j);
|
unsigned int domain_len = (i - j);
|
||||||
const char *sni_startp = sni_name + sni_len - domain_len;
|
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 &&
|
if (sni_len >= domain_len &&
|
||||||
sni_len < 128 &&
|
sni_len < 128 &&
|
||||||
@ -203,7 +204,7 @@ out:
|
|||||||
|
|
||||||
|
|
||||||
brute:
|
brute:
|
||||||
if (config.all_domains) {
|
if (section->all_domains) {
|
||||||
vrd.target_sni = 1;
|
vrd.target_sni = 1;
|
||||||
vrd.sni_len = 0;
|
vrd.sni_len = 0;
|
||||||
vrd.sni_offset = dlen / 2;
|
vrd.sni_offset = dlen / 2;
|
||||||
@ -211,15 +212,15 @@ brute:
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int j = 0;
|
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 &&
|
if ( i > j &&
|
||||||
(i == config.domains_strlen ||
|
(i == section->domains_strlen ||
|
||||||
config.domains_str[i] == '\0' ||
|
section->domains_str[i] == '\0' ||
|
||||||
config.domains_str[i] == ',' ||
|
section->domains_str[i] == ',' ||
|
||||||
config.domains_str[i] == '\n' )) {
|
section->domains_str[i] == '\n' )) {
|
||||||
|
|
||||||
unsigned int domain_len = (i - j);
|
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) {
|
if (domain_len + dlen + 1> MAX_PACKET_SIZE) {
|
||||||
continue;
|
continue;
|
||||||
|
2
tls.h
2
tls.h
@ -20,7 +20,7 @@ struct tls_verdict {
|
|||||||
* Processes the packet and finds TLS Client Hello information inside it.
|
* Processes the packet and finds TLS Client Hello information inside it.
|
||||||
* data pointer points to start of TLS Message (TCP Payload)
|
* 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
24
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 = {
|
struct failing_strategy fl_strat = {
|
||||||
.strategy = (unsigned int)config.faking_strategy,
|
.strategy = (unsigned int)section->faking_strategy,
|
||||||
.faking_ttl = config.faking_ttl,
|
.faking_ttl = section->faking_ttl,
|
||||||
.randseq_offset = (uint32_t)config.fakeseq_offset
|
.randseq_offset = (uint32_t)section->fakeseq_offset
|
||||||
};
|
};
|
||||||
return fl_strat;
|
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 = {
|
struct fake_type f_type = {
|
||||||
.sequence_len = config.fake_sni_seq_len,
|
.sequence_len = section->fake_sni_seq_len,
|
||||||
.strategy = args_default_failing_strategy(),
|
.strategy = args_default_failing_strategy(section),
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (config.fake_sni_type) {
|
switch (section->fake_sni_type) {
|
||||||
case FAKE_PAYLOAD_RANDOM:
|
case FAKE_PAYLOAD_RANDOM:
|
||||||
f_type.type = FAKE_PAYLOAD_RANDOM;
|
f_type.type = FAKE_PAYLOAD_RANDOM;
|
||||||
break;
|
break;
|
||||||
case FAKE_PAYLOAD_CUSTOM:
|
case FAKE_PAYLOAD_CUSTOM:
|
||||||
f_type.type = FAKE_PAYLOAD_CUSTOM;
|
f_type.type = FAKE_PAYLOAD_CUSTOM;
|
||||||
f_type.fake_data = config.fake_custom_pkt;
|
f_type.fake_data = section->fake_custom_pkt;
|
||||||
f_type.fake_len = config.fake_custom_pkt_sz;
|
f_type.fake_len = section->fake_custom_pkt_sz;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
f_type.type = FAKE_PAYLOAD_CUSTOM;
|
f_type.type = FAKE_PAYLOAD_CUSTOM;
|
||||||
f_type.fake_data = config.fake_sni_pkt;
|
f_type.fake_data = section->fake_sni_pkt;
|
||||||
f_type.fake_len = config.fake_sni_pkt_sz;
|
f_type.fake_len = section->fake_sni_pkt_sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
return f_type;
|
return f_type;
|
||||||
|
@ -264,27 +264,11 @@ static int send_raw_socket(const uint8_t *pkt, uint32_t pktlen) {
|
|||||||
uint8_t buff2[MNL_SOCKET_BUFFER_SIZE];
|
uint8_t buff2[MNL_SOCKET_BUFFER_SIZE];
|
||||||
uint32_t buff2_size = MNL_SOCKET_BUFFER_SIZE;
|
uint32_t buff2_size = MNL_SOCKET_BUFFER_SIZE;
|
||||||
|
|
||||||
switch (config.fragmentation_strategy) {
|
if ((ret = tcp_frag(pkt, pktlen, AVAILABLE_MTU-128,
|
||||||
case FRAG_STRAT_TCP:
|
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;
|
errno = -ret;
|
||||||
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user