mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2024-12-30 14:45:19 +00:00
Add args for UDP faking support.
This commit is contained in:
parent
7480cd31b8
commit
f9a51944dd
21
README.md
21
README.md
@ -133,7 +133,8 @@ Copy `youtubeUnblock.service` to `/usr/lib/systemd/system` (you should change th
|
||||
On nftables you should put next nftables rules:
|
||||
```sh
|
||||
nft add chain inet fw4 youtubeUnblock '{ type filter hook postrouting priority mangle - 1; policy accept; }'
|
||||
nft add rule inet fw4 youtubeUnblock 'meta l4proto { tcp, udp } th dport 443 ct original packets < 20 counter queue num 537 bypass'
|
||||
nft add rule inet fw4 youtubeUnblock 'tcp dport 443 ct original packets < 20 counter queue num 537 bypass'
|
||||
nft add rule inet fw4 youtubeUnblock 'meta l4proto udp ct original packets < 9 counter queue num 537 bypass'
|
||||
nft insert rule inet fw4 output 'mark and 0x8000 == 0x8000 counter accept'
|
||||
```
|
||||
|
||||
@ -143,7 +144,7 @@ On iptables you should put next iptables rules:
|
||||
```sh
|
||||
iptables -t mangle -N YOUTUBEUNBLOCK
|
||||
iptables -t mangle -A YOUTUBEUNBLOCK -p tcp --dport 443 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 537 --queue-bypass
|
||||
iptables -t mangle -A YOUTUBEUNBLOCK -p udp --dport 443 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 537 --queue-bypass
|
||||
iptables -t mangle -A YOUTUBEUNBLOCK -p udp -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:8 -j NFQUEUE --queue-num 537 --queue-bypass
|
||||
iptables -t mangle -A POSTROUTING -j YOUTUBEUNBLOCK
|
||||
iptables -I OUTPUT -m mark --mark 32768/32768 -j ACCEPT
|
||||
```
|
||||
@ -154,7 +155,7 @@ For IPv6 on iptables you need to duplicate rules above for ip6tables:
|
||||
```sh
|
||||
ip6tables -t mangle -N YOUTUBEUNBLOCK
|
||||
ip6tables -t mangle -A YOUTUBEUNBLOCK -p tcp --dport 443 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 537 --queue-bypass
|
||||
ip6tables -t mangle -A YOUTUBEUNBLOCK -p udp --dport 443 -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:19 -j NFQUEUE --queue-num 537 --queue-bypass
|
||||
ip6tables -t mangle -A YOUTUBEUNBLOCK -p udp -m connbytes --connbytes-dir original --connbytes-mode packets --connbytes 0:8 -j NFQUEUE --queue-num 537 --queue-bypass
|
||||
ip6tables -t mangle -A POSTROUTING -j YOUTUBEUNBLOCK
|
||||
ip6tables -I OUTPUT -m mark --mark 32768/32768 -j ACCEPT
|
||||
```
|
||||
@ -219,8 +220,6 @@ Available flags:
|
||||
|
||||
- `--frag-sni-pos=<pos>` With this option **youtubeUnblock** will split the packet at the position pos. Defaults to 1.
|
||||
|
||||
- `--quic-drop` Drop all QUIC packets which goes to youtubeUnblock. Won't affect any other UDP packets. Suitable for some TVs. Note, that for this option to work you should also add proxy udp to youtubeUnblock in firewall. `connbytes` may also be used with udp.
|
||||
|
||||
- `--fk-winsize=<winsize>` Specifies window size for the fragmented TCP packet. Applicable if you want for response to be fragmented. May slowdown connection initialization.
|
||||
|
||||
- `--synfake={1|0}` If 1, syn payload will be sent before each request. The idea is taken from syndata from zapret project. Syn payload will normally be discarded by endpoint but may be handled by TSPU. This option sends normal fake in that payload. Please note, that the option works for all the sites, so --sni-domains won't change anything.
|
||||
@ -231,6 +230,18 @@ Available flags:
|
||||
|
||||
- `--seg2delay=<delay>` This flag forces **youtubeUnblock** to wait a little bit before send the 2nd part of the split packet.
|
||||
|
||||
- `--udp-mode={drop|fake}` This flag specifies udp handling strategy. If drop udp packets will be dropped (useful for quic when browser can fallback to tcp), if fake udp will be faked. Defaults to fake.
|
||||
|
||||
- `--udp-fake-seq-len=<amount of faking packets sent>` Specifies how much faking packets will be sent over the network. Defaults to 6.
|
||||
|
||||
- `--udp-fake-len=<size of udp fake>` Size of udp fake payload (typically payload is zeroes). Defaults to 64.
|
||||
|
||||
- `--udp-dport-filter=<5,6,200-500>` Filter the UDP destination ports. Defaults to no ports. Specifie the ports you want to be handled by youtubeUnblock.
|
||||
|
||||
- `--udp-filter-quic={disabled|all}` Enables QUIC filtering for UDP handler. If disabled, quic won't be processed, if all all quic initial packets will be handled. Defaults to disabled.
|
||||
|
||||
- `--quic-drop` Drop all QUIC packets which goes to youtubeUnblock. Won't affect any other UDP packets. Just an alias for `--udp-filter-quic=all --udp-mode=drop`.
|
||||
|
||||
- `--silent` Disables verbose mode.
|
||||
|
||||
- `--trace` Maximum verbosity for debugging purposes.
|
||||
|
163
args.c
163
args.c
@ -62,6 +62,12 @@ enum {
|
||||
OPT_SILENT,
|
||||
OPT_NO_GSO,
|
||||
OPT_QUEUE_NUM,
|
||||
OPT_UDP_MODE,
|
||||
OPT_UDP_FAKE_SEQ_LEN,
|
||||
OPT_UDP_FAKE_PAYLOAD_LEN,
|
||||
OPT_UDP_FAKING_STRATEGY,
|
||||
OPT_UDP_DPORT_FILTER,
|
||||
OPT_UDP_FILTER_QUIC,
|
||||
};
|
||||
|
||||
static struct option long_opt[] = {
|
||||
@ -87,6 +93,12 @@ static struct option long_opt[] = {
|
||||
{"quic-drop", 0, 0, OPT_QUIC_DROP},
|
||||
{"sni-detection", 1, 0, OPT_SNI_DETECTION},
|
||||
{"seg2delay", 1, 0, OPT_SEG2DELAY},
|
||||
{"udp-mode", 1, 0, OPT_UDP_MODE},
|
||||
{"udp-fake-seq-len", 1, 0, OPT_UDP_FAKE_SEQ_LEN},
|
||||
{"udp-fake-len", 1, 0, OPT_UDP_FAKE_PAYLOAD_LEN},
|
||||
{"udp-faking-strategy", 1, 0, OPT_UDP_FAKING_STRATEGY},
|
||||
{"udp-dport-filter", 1, 0, OPT_UDP_DPORT_FILTER},
|
||||
{"udp-filter-quic", 1, 0, OPT_UDP_FILTER_QUIC},
|
||||
{"threads", 1, 0, OPT_THREADS},
|
||||
{"silent", 0, 0, OPT_SILENT},
|
||||
{"trace", 0, 0, OPT_TRACE},
|
||||
@ -157,6 +169,12 @@ void print_usage(const char *argv0) {
|
||||
printf("\t--quic-drop\n");
|
||||
printf("\t--sni-detection={parse|brute}\n");
|
||||
printf("\t--seg2delay=<delay>\n");
|
||||
printf("\t--udp-mode={drop|fake}\n");
|
||||
printf("\t--udp-fake-seq-len=<amount of faking packets sent>\n");
|
||||
printf("\t--udp-fake-len=<size of upd fake>\n");
|
||||
printf("\t--udp-faking-strategy={checksum|ttl}\n");
|
||||
printf("\t--udp-dport-filter=<5,6,200-500>\n");
|
||||
printf("\t--udp-filter-quic={disabled|all}\n");
|
||||
printf("\t--threads=<threads number>\n");
|
||||
printf("\t--packet-mark=<mark>\n");
|
||||
printf("\t--silent\n");
|
||||
@ -171,6 +189,87 @@ void print_usage(const char *argv0) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int parse_udp_dport_range(char *str, struct udp_dport_range **udpr, int *udpr_len) {
|
||||
int ret = 0;
|
||||
int seclen = 1;
|
||||
int strlen = 0;
|
||||
const char *p = optarg;
|
||||
while (*p != '\0') {
|
||||
if (*p == ',')
|
||||
seclen++;
|
||||
p++;
|
||||
}
|
||||
strlen = p - optarg;
|
||||
|
||||
struct udp_dport_range *udp_dport_ranges = malloc(
|
||||
seclen * sizeof(struct udp_dport_range));
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
||||
p = optarg;
|
||||
const char *ep = p;
|
||||
while (1) {
|
||||
if (*ep == '\0' || *ep == ',') {
|
||||
if (ep == p) {
|
||||
if (*ep == '\0')
|
||||
break;
|
||||
|
||||
p++, ep++;
|
||||
continue;
|
||||
}
|
||||
|
||||
char *endp;
|
||||
long num1 = strtol(p, &endp, 10);
|
||||
long num2 = num1;
|
||||
if (errno)
|
||||
goto erret;
|
||||
|
||||
if (endp != ep) {
|
||||
if (*endp == '-') {
|
||||
endp++;
|
||||
num2 = strtol(endp, &endp, 10);
|
||||
|
||||
if (endp != ep || errno)
|
||||
goto erret;
|
||||
} else {
|
||||
goto erret;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!(num1 > 0 && num1 < (1 << 16)) ||
|
||||
!(num2 > 0 && num2 < (1 << 16)) ||
|
||||
num2 < num1
|
||||
)
|
||||
goto erret;
|
||||
|
||||
udp_dport_ranges[i] = (struct udp_dport_range){
|
||||
.start = num1,
|
||||
.end = num2
|
||||
};
|
||||
i++;
|
||||
|
||||
if (*ep == '\0') {
|
||||
break;
|
||||
} else {
|
||||
p = ep + 1;
|
||||
ep = p;
|
||||
}
|
||||
} else {
|
||||
ep++;
|
||||
}
|
||||
}
|
||||
|
||||
*udpr = udp_dport_ranges;
|
||||
*udpr_len = seclen;
|
||||
return 0;
|
||||
|
||||
erret:
|
||||
free(udp_dport_ranges);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int parse_args(int argc, char *argv[]) {
|
||||
int opt;
|
||||
int optIdx = 0;
|
||||
@ -443,7 +542,8 @@ int parse_args(int argc, char *argv[]) {
|
||||
sect_config->seg2_delay = num;
|
||||
break;
|
||||
case OPT_QUIC_DROP:
|
||||
sect_config->quic_drop = 1;
|
||||
sect_config->udp_filter_quic = UDP_FILTER_QUIC_ALL;
|
||||
sect_config->udp_mode = UDP_MODE_DROP;
|
||||
break;
|
||||
case OPT_SNI_DETECTION:
|
||||
if (strcmp(optarg, "parse") == 0) {
|
||||
@ -471,6 +571,63 @@ int parse_args(int argc, char *argv[]) {
|
||||
goto invalid_opt;
|
||||
}
|
||||
sect_config->synfake_len = num;
|
||||
break;
|
||||
case OPT_UDP_MODE:
|
||||
if (strcmp(optarg, "drop") == 0) {
|
||||
sect_config->udp_mode = UDP_MODE_DROP;
|
||||
} else if (strcmp(optarg, "fake") == 0) {
|
||||
sect_config->udp_mode = UDP_MODE_FAKE;
|
||||
} else {
|
||||
goto invalid_opt;
|
||||
}
|
||||
|
||||
break;
|
||||
case OPT_UDP_FAKING_STRATEGY:
|
||||
if (strcmp(optarg, "checksum") == 0) {
|
||||
sect_config->udp_faking_strategy = FAKE_STRAT_UDP_CHECK;
|
||||
} else if (strcmp(optarg, "ttl") == 0) {
|
||||
sect_config->udp_faking_strategy = FAKE_STRAT_TTL;
|
||||
} else {
|
||||
goto invalid_opt;
|
||||
}
|
||||
|
||||
break;
|
||||
case OPT_UDP_FAKE_SEQ_LEN:
|
||||
num = parse_numeric_option(optarg);
|
||||
if (errno != 0 || num < 0) {
|
||||
goto invalid_opt;
|
||||
}
|
||||
|
||||
sect_config->udp_fake_seq_len = num;
|
||||
break;
|
||||
case OPT_UDP_FAKE_PAYLOAD_LEN:
|
||||
num = parse_numeric_option(optarg);
|
||||
if (errno != 0 || num < 0 || num > 1300) {
|
||||
goto invalid_opt;
|
||||
}
|
||||
|
||||
sect_config->udp_fake_len = num;
|
||||
break;
|
||||
case OPT_UDP_DPORT_FILTER:
|
||||
{
|
||||
struct udp_dport_range *udp_dport_range;
|
||||
int udp_range_len = 0;
|
||||
if (parse_udp_dport_range(optarg, &udp_dport_range, &udp_range_len) < 0) {
|
||||
goto invalid_opt;
|
||||
}
|
||||
sect_config->udp_dport_range = udp_dport_range;
|
||||
sect_config->udp_dport_range_len = udp_range_len;
|
||||
break;
|
||||
}
|
||||
case OPT_UDP_FILTER_QUIC:
|
||||
if (strcmp(optarg, "disabled") == 0) {
|
||||
sect_config->udp_filter_quic = UDP_FILTER_QUIC_DISABLED;
|
||||
} else if (strcmp(optarg, "all") == 0) {
|
||||
sect_config->udp_filter_quic = UDP_FILTER_QUIC_ALL;
|
||||
} else {
|
||||
goto invalid_opt;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
@ -490,7 +647,7 @@ invalid_opt:
|
||||
error:
|
||||
print_usage(argv[0]);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
void print_welcome() {
|
||||
@ -575,7 +732,7 @@ void print_welcome() {
|
||||
lginfo("Fake SYN payload will be sent with each TCP request SYN packet\n");
|
||||
}
|
||||
|
||||
if (section->quic_drop) {
|
||||
if (section->udp_filter_quic && section->udp_mode == UDP_MODE_DROP) {
|
||||
lginfo("All QUIC packets will be dropped\n");
|
||||
}
|
||||
|
||||
|
95
config.h
95
config.h
@ -6,6 +6,7 @@
|
||||
#endif
|
||||
|
||||
#include "raw_replacements.h"
|
||||
#include "types.h"
|
||||
|
||||
typedef int (*raw_send_t)(const unsigned char *data, unsigned int data_len);
|
||||
/**
|
||||
@ -20,6 +21,11 @@ struct instance_config_t {
|
||||
};
|
||||
extern struct instance_config_t instance_config;
|
||||
|
||||
struct udp_dport_range {
|
||||
uint16_t start;
|
||||
uint16_t end;
|
||||
};
|
||||
|
||||
struct section_config_t {
|
||||
const char *domains_str;
|
||||
unsigned int domains_strlen;
|
||||
@ -40,8 +46,6 @@ struct section_config_t {
|
||||
#define FAKE_PAYLOAD_DEFAULT 2
|
||||
int fake_sni_type;
|
||||
|
||||
int quic_drop;
|
||||
|
||||
/* In milliseconds */
|
||||
unsigned int seg2_delay;
|
||||
int synfake;
|
||||
@ -64,6 +68,14 @@ struct section_config_t {
|
||||
#define SNI_DETECTION_BRUTE 1
|
||||
int sni_detection;
|
||||
|
||||
int udp_mode;
|
||||
unsigned int udp_fake_seq_len;
|
||||
unsigned int udp_fake_len;
|
||||
int udp_faking_strategy;
|
||||
|
||||
struct udp_dport_range *udp_dport_range;
|
||||
int udp_dport_range_len;
|
||||
int udp_filter_quic;
|
||||
};
|
||||
|
||||
#define MAX_CONFIGLIST_LEN 64
|
||||
@ -96,37 +108,6 @@ for (struct section_config_t *section = &config.default_config + config.custom_c
|
||||
|
||||
#define CONFIG_SECTION_NUMBER(section) (int)((section) - &config.default_config)
|
||||
|
||||
#define default_section_config { \
|
||||
.frag_sni_reverse = 1, \
|
||||
.frag_sni_faked = 0, \
|
||||
.fragmentation_strategy = FRAGMENTATION_STRATEGY, \
|
||||
.faking_strategy = FAKING_STRATEGY, \
|
||||
.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, \
|
||||
.fakeseq_offset = 10000, \
|
||||
.synfake = 0, \
|
||||
.synfake_len = 0, \
|
||||
.quic_drop = 0, \
|
||||
\
|
||||
.seg2_delay = 0, \
|
||||
\
|
||||
.domains_str = defaul_snistr, \
|
||||
.domains_strlen = sizeof(defaul_snistr), \
|
||||
\
|
||||
.exclude_domains_str = "", \
|
||||
.exclude_domains_strlen = 0, \
|
||||
\
|
||||
.fake_sni_pkt = fake_sni_old, \
|
||||
.fake_sni_pkt_sz = sizeof(fake_sni_old) - 1, \
|
||||
.fake_custom_pkt = custom_fake_buf, \
|
||||
.fake_custom_pkt_sz = 0, \
|
||||
.sni_detection = SNI_DETECTION_PARSE, \
|
||||
}
|
||||
|
||||
#define MAX_THREADS 16
|
||||
|
||||
#ifndef THREADS_NUM
|
||||
@ -199,4 +180,52 @@ if ((fake_bitmask) & strategy)
|
||||
|
||||
static const char defaul_snistr[] = DEFAULT_SNISTR;
|
||||
|
||||
enum {
|
||||
UDP_MODE_DROP,
|
||||
UDP_MODE_FAKE,
|
||||
};
|
||||
|
||||
enum {
|
||||
UDP_FILTER_QUIC_DISABLED,
|
||||
UDP_FILTER_QUIC_ALL,
|
||||
};
|
||||
|
||||
#define default_section_config { \
|
||||
.frag_sni_reverse = 1, \
|
||||
.frag_sni_faked = 0, \
|
||||
.fragmentation_strategy = FRAGMENTATION_STRATEGY, \
|
||||
.faking_strategy = FAKING_STRATEGY, \
|
||||
.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, \
|
||||
.fakeseq_offset = 10000, \
|
||||
.synfake = 0, \
|
||||
.synfake_len = 0, \
|
||||
\
|
||||
.seg2_delay = 0, \
|
||||
\
|
||||
.domains_str = defaul_snistr, \
|
||||
.domains_strlen = sizeof(defaul_snistr), \
|
||||
\
|
||||
.exclude_domains_str = "", \
|
||||
.exclude_domains_strlen = 0, \
|
||||
\
|
||||
.fake_sni_pkt = fake_sni_old, \
|
||||
.fake_sni_pkt_sz = sizeof(fake_sni_old) - 1, \
|
||||
.fake_custom_pkt = custom_fake_buf, \
|
||||
.fake_custom_pkt_sz = 0, \
|
||||
.sni_detection = SNI_DETECTION_PARSE, \
|
||||
\
|
||||
.udp_mode = UDP_MODE_FAKE, \
|
||||
.udp_fake_seq_len = 6, \
|
||||
.udp_fake_len = 64, \
|
||||
.udp_faking_strategy = FAKE_STRAT_UDP_CHECK, \
|
||||
.udp_dport_range = NULL, \
|
||||
.udp_dport_range_len = 0, \
|
||||
.udp_filter_quic = UDP_FILTER_QUIC_DISABLED, \
|
||||
}
|
||||
|
||||
#endif /* YTB_CONFIG_H */
|
||||
|
2
kargs.c
2
kargs.c
@ -161,7 +161,7 @@ static const struct kernel_param_ops exclude_domains_ops = {
|
||||
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, &def_section->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;
|
||||
|
44
mangle.c
44
mangle.c
@ -363,43 +363,13 @@ int process_udp_packet(const struct section_config_t *section, const uint8_t *pk
|
||||
}
|
||||
|
||||
|
||||
if (!detect_udp_filtered(section, pkt, pktlen))
|
||||
goto continue_flow;
|
||||
|
||||
if (section->quic_drop) {
|
||||
lgtrace_addp("QUIC probe");
|
||||
const struct quic_lhdr *qch;
|
||||
uint32_t qch_len;
|
||||
struct quic_cids qci;
|
||||
uint8_t *quic_raw_payload;
|
||||
uint32_t quic_raw_plen;
|
||||
ret = quic_parse_data((uint8_t *)data, dlen,
|
||||
(struct quic_lhdr **)&qch, &qch_len, &qci,
|
||||
&quic_raw_payload, &quic_raw_plen);
|
||||
|
||||
if (ret < 0) {
|
||||
lgtrace_addp("undefined type");
|
||||
goto accept_quic;
|
||||
}
|
||||
|
||||
lgtrace_addp("QUIC detected");
|
||||
uint8_t qtype = qch->type;
|
||||
|
||||
if (section->udp_mode == UDP_MODE_DROP)
|
||||
goto drop;
|
||||
|
||||
if (qch->version == QUIC_V1)
|
||||
qtype = quic_convtype_v1(qtype);
|
||||
else if (qch->version == QUIC_V2)
|
||||
qtype = quic_convtype_v2(qtype);
|
||||
|
||||
if (qtype != QUIC_INITIAL_TYPE) {
|
||||
lgtrace_addp("quic message type: %d", qtype);
|
||||
goto accept_quic;
|
||||
}
|
||||
|
||||
lgtrace_addp("quic initial message");
|
||||
}
|
||||
|
||||
if (1) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
else if (section->udp_mode == UDP_MODE_FAKE) {
|
||||
for (int i = 0; i < section->udp_fake_seq_len; i++) {
|
||||
NETBUF_ALLOC(fake_udp, MAX_PACKET_SIZE);
|
||||
if (!NETBUF_CHECK(fake_udp)) {
|
||||
lgerror(-ENOMEM, "Allocation error");
|
||||
@ -408,9 +378,9 @@ int process_udp_packet(const struct section_config_t *section, const uint8_t *pk
|
||||
uint32_t fsn_len = MAX_PACKET_SIZE;
|
||||
|
||||
struct udp_fake_type fake_type = {
|
||||
.fake_len = 64,
|
||||
.fake_len = section->udp_fake_len,
|
||||
.strategy = {
|
||||
.strategy = FAKE_STRAT_UDP_CHECK,
|
||||
.strategy = section->udp_faking_strategy,
|
||||
},
|
||||
};
|
||||
ret = gen_fake_udp(fake_type, iph, iph_len, udph, fake_udp, &fsn_len);
|
||||
|
76
quic.c
76
quic.c
@ -179,7 +179,7 @@ int udp_fail_packet(struct udp_failing_strategy strategy, uint8_t *payload, uint
|
||||
set_ip_checksum(iph, iph_len);
|
||||
|
||||
if (strategy.strategy == FAKE_STRAT_UDP_CHECK) {
|
||||
lgtrace_addp("break fake tcp checksum");
|
||||
lgtrace_addp("break fake udp checksum");
|
||||
udph->check += 1;
|
||||
}
|
||||
|
||||
@ -247,3 +247,77 @@ int gen_fake_udp(struct udp_fake_type type,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int detect_udp_filtered(const struct section_config_t *section,
|
||||
const uint8_t *payload, uint32_t plen) {
|
||||
const void *iph;
|
||||
uint32_t iph_len;
|
||||
const struct udphdr *udph;
|
||||
const uint8_t *data;
|
||||
uint32_t dlen;
|
||||
int ret;
|
||||
int ipver;
|
||||
|
||||
ipver = netproto_version(payload, plen);
|
||||
|
||||
ret = udp_payload_split((uint8_t *)payload, plen,
|
||||
(void **)&iph, &iph_len,
|
||||
(struct udphdr **)&udph,
|
||||
(uint8_t **)&data, &dlen);
|
||||
int udp_dport = ntohs(udph->dest);
|
||||
lgtrace_addp("UDP dport: %d", udp_dport);
|
||||
|
||||
|
||||
if (ret < 0) {
|
||||
goto skip;
|
||||
}
|
||||
|
||||
if (section->udp_filter_quic) {
|
||||
const struct quic_lhdr *qch;
|
||||
uint32_t qch_len;
|
||||
struct quic_cids qci;
|
||||
uint8_t *quic_raw_payload;
|
||||
uint32_t quic_raw_plen;
|
||||
|
||||
lgtrace_addp("QUIC probe");
|
||||
|
||||
ret = quic_parse_data((uint8_t *)data, dlen,
|
||||
(struct quic_lhdr **)&qch, &qch_len, &qci,
|
||||
&quic_raw_payload, &quic_raw_plen);
|
||||
|
||||
if (ret < 0) {
|
||||
lgtrace_addp("undefined type");
|
||||
goto skip;
|
||||
}
|
||||
|
||||
lgtrace_addp("QUIC detected");
|
||||
uint8_t qtype = qch->type;
|
||||
|
||||
goto approve;
|
||||
|
||||
// if (qch->version == QUIC_V1)
|
||||
// qtype = quic_convtype_v1(qtype);
|
||||
// else if (qch->version == QUIC_V2)
|
||||
// qtype = quic_convtype_v2(qtype);
|
||||
//
|
||||
// if (qtype != QUIC_INITIAL_TYPE) {
|
||||
// lgtrace_addp("quic message type: %d", qtype);
|
||||
// goto accept_quic;
|
||||
// }
|
||||
//
|
||||
// lgtrace_addp("quic initial message");
|
||||
}
|
||||
|
||||
for (int i = 0; i < section->udp_dport_range_len; i++) {
|
||||
struct udp_dport_range crange = section->udp_dport_range[i];
|
||||
if (udp_dport >= crange.start && udp_dport <= crange.end) {
|
||||
lgtrace_addp("matched to %d-%d", crange.start, crange.end);
|
||||
goto approve;
|
||||
}
|
||||
}
|
||||
|
||||
skip:
|
||||
return 0;
|
||||
approve:
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user