mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2024-12-30 14:45:19 +00:00
UDP faking support
This commit is contained in:
parent
5ee77d517b
commit
b2ac2e0d03
3
config.h
3
config.h
@ -165,8 +165,9 @@ for (struct section_config_t *section = &config.default_config + config.custom_c
|
||||
#define FAKE_STRAT_PAST_SEQ (1 << 2)
|
||||
#define FAKE_STRAT_TCP_CHECK (1 << 3)
|
||||
#define FAKE_STRAT_TCP_MD5SUM (1 << 4)
|
||||
#define FAKE_STRAT_UDP_CHECK (1 << 5)
|
||||
|
||||
#define FAKE_STRAT_COUNT 5
|
||||
#define FAKE_STRAT_COUNT 6
|
||||
|
||||
/**
|
||||
* This macros iterates through all faking strategies and executes code under it.
|
||||
|
81
mangle.c
81
mangle.c
@ -74,16 +74,32 @@ int process_packet(const uint8_t *raw_payload, uint32_t raw_payload_len) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (verdict == PKT_CONTINUE)
|
||||
if (verdict == PKT_CONTINUE) {
|
||||
lgtrace_addp("continue_flow");
|
||||
continue;
|
||||
}
|
||||
|
||||
lgtrace_end();
|
||||
return verdict;
|
||||
goto ret_verdict;
|
||||
}
|
||||
|
||||
accept:
|
||||
verdict = PKT_ACCEPT;
|
||||
|
||||
ret_verdict:
|
||||
|
||||
switch (verdict) {
|
||||
case PKT_ACCEPT:
|
||||
lgtrace_addp("accept");
|
||||
break;
|
||||
case PKT_DROP:
|
||||
lgtrace_addp("drop");
|
||||
break;
|
||||
default:
|
||||
lgtrace_addp("unknow verdict: %d", verdict);
|
||||
}
|
||||
lgtrace_end();
|
||||
return PKT_ACCEPT;
|
||||
|
||||
return verdict;
|
||||
}
|
||||
|
||||
int process_tcp_packet(const struct section_config_t *section, const uint8_t *raw_payload, uint32_t raw_payload_len) {
|
||||
@ -309,13 +325,10 @@ drop_lc:
|
||||
}
|
||||
|
||||
continue_flow:
|
||||
lgtrace_addp("continue_flow");
|
||||
return PKT_CONTINUE;
|
||||
accept:
|
||||
lgtrace_addp("accept");
|
||||
return PKT_ACCEPT;
|
||||
drop:
|
||||
lgtrace_addp("drop");
|
||||
return PKT_DROP;
|
||||
}
|
||||
|
||||
@ -350,6 +363,7 @@ int process_udp_packet(const struct section_config_t *section, const uint8_t *pk
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (section->quic_drop) {
|
||||
lgtrace_addp("QUIC probe");
|
||||
const struct quic_lhdr *qch;
|
||||
@ -384,39 +398,48 @@ int process_udp_packet(const struct section_config_t *section, const uint8_t *pk
|
||||
lgtrace_addp("quic initial message");
|
||||
}
|
||||
|
||||
/*
|
||||
if (1) {
|
||||
lgtrace_addp("Probe udp");
|
||||
if (ipver == IP4VERSION && ntohs(udph->dest) > 30) {
|
||||
lgtrace_addp("udp fool");
|
||||
const uint8_t *payload;
|
||||
uint32_t payload_len;
|
||||
|
||||
uint32_t poses[10];
|
||||
int cnt = 3;
|
||||
|
||||
poses[0] = 8;
|
||||
for (int i = 1; i < cnt; i++) {
|
||||
poses[i] = poses[i - 1] + 8;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
NETBUF_ALLOC(fake_udp, MAX_PACKET_SIZE);
|
||||
if (!NETBUF_CHECK(fake_udp)) {
|
||||
lgerror(-ENOMEM, "Allocation error");
|
||||
return -ENOMEM;
|
||||
}
|
||||
uint32_t fsn_len = MAX_PACKET_SIZE;
|
||||
|
||||
ret = send_ip4_frags(pkt, pktlen, poses, cnt, 0);
|
||||
struct udp_fake_type fake_type = {
|
||||
.fake_len = 64,
|
||||
.strategy = {
|
||||
.strategy = FAKE_STRAT_UDP_CHECK,
|
||||
},
|
||||
};
|
||||
ret = gen_fake_udp(fake_type, iph, iph_len, udph, fake_udp, &fsn_len);
|
||||
if (ret < 0) {
|
||||
lgerror("ip4 send frags", ret);
|
||||
goto accept;
|
||||
lgerror(ret, "gen_fake_udp");
|
||||
goto erret_lc;
|
||||
}
|
||||
|
||||
goto drop;
|
||||
} else {
|
||||
lginfo("WARNING: IP fragmentation is supported only for IPv4\n");
|
||||
lgtrace_addp("post fake udp #%d", i + 1);
|
||||
|
||||
ret = instance_config.send_raw_packet(fake_udp, fsn_len);
|
||||
if (ret < 0) {
|
||||
lgerror(ret, "send fake udp");
|
||||
goto erret_lc;
|
||||
}
|
||||
|
||||
NETBUF_FREE(fake_udp);
|
||||
continue;
|
||||
erret_lc:
|
||||
NETBUF_FREE(fake_udp);
|
||||
goto accept;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
ret = instance_config.send_raw_packet(pkt, pktlen);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
continue_flow:
|
||||
lgtrace_addp("continue_flow");
|
||||
return PKT_CONTINUE;
|
||||
accept_quic:
|
||||
accept:
|
||||
|
109
quic.c
109
quic.c
@ -138,3 +138,112 @@ invalid_packet:
|
||||
lgerror(-EINVAL, "QUIC invalid Initial packet");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int udp_fail_packet(struct udp_failing_strategy strategy, uint8_t *payload, uint32_t *plen, uint32_t avail_buflen) {
|
||||
void *iph;
|
||||
uint32_t iph_len;
|
||||
struct udphdr *udph;
|
||||
uint8_t *data;
|
||||
uint32_t dlen;
|
||||
int ret;
|
||||
|
||||
ret = udp_payload_split(payload, *plen,
|
||||
&iph, &iph_len, &udph,
|
||||
&data, &dlen);
|
||||
|
||||
uint32_t ipxv = netproto_version(payload, *plen);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (strategy.strategy == FAKE_STRAT_TTL) {
|
||||
lgtrace_addp("set fake ttl to %d", strategy.faking_ttl);
|
||||
|
||||
if (ipxv == IP4VERSION) {
|
||||
((struct iphdr *)iph)->ttl = strategy.faking_ttl;
|
||||
} else if (ipxv == IP6VERSION) {
|
||||
((struct ip6_hdr *)iph)->ip6_hops = strategy.faking_ttl;
|
||||
} else {
|
||||
lgerror(-EINVAL, "fail_packet: IP version is unsupported");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ipxv == IP4VERSION) {
|
||||
((struct iphdr *)iph)->frag_off = 0;
|
||||
}
|
||||
|
||||
|
||||
set_ip_checksum(iph, iph_len);
|
||||
|
||||
if (strategy.strategy == FAKE_STRAT_UDP_CHECK) {
|
||||
lgtrace_addp("break fake tcp checksum");
|
||||
udph->check += 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gen_fake_udp(struct udp_fake_type type,
|
||||
const void *ipxh, uint32_t iph_len,
|
||||
const struct udphdr *udph,
|
||||
uint8_t *buf, uint32_t *buflen) {
|
||||
uint32_t data_len = type.fake_len;
|
||||
int ret;
|
||||
|
||||
|
||||
if (!ipxh || !udph || !buf || !buflen)
|
||||
return -EINVAL;
|
||||
|
||||
int ipxv = netproto_version(ipxh, iph_len);
|
||||
|
||||
if (ipxv == IP4VERSION) {
|
||||
const struct iphdr *iph = ipxh;
|
||||
|
||||
memcpy(buf, iph, iph_len);
|
||||
struct iphdr *niph = (struct iphdr *)buf;
|
||||
|
||||
niph->protocol = IPPROTO_UDP;
|
||||
} else if (ipxv == IP6VERSION) {
|
||||
const struct ip6_hdr *iph = ipxh;
|
||||
|
||||
iph_len = sizeof(struct ip6_hdr);
|
||||
memcpy(buf, iph, iph_len);
|
||||
struct ip6_hdr *niph = (struct ip6_hdr *)buf;
|
||||
|
||||
niph->ip6_nxt = IPPROTO_UDP;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
uint32_t dlen = iph_len + sizeof(struct udphdr) + data_len;
|
||||
|
||||
if (*buflen < dlen)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(buf + iph_len, udph, sizeof(struct udphdr));
|
||||
uint8_t *bfdptr = buf + iph_len + sizeof(struct udphdr);
|
||||
|
||||
memset(bfdptr, 0, data_len);
|
||||
|
||||
if (ipxv == IP4VERSION) {
|
||||
struct iphdr *niph = (struct iphdr *)buf;
|
||||
niph->tot_len = htons(dlen);
|
||||
niph->id = randint();
|
||||
} else if (ipxv == IP6VERSION) {
|
||||
struct ip6_hdr *niph = (struct ip6_hdr *)buf;
|
||||
niph->ip6_plen = htons(dlen - iph_len);
|
||||
}
|
||||
|
||||
struct udphdr *nudph = (struct udphdr *)(buf + iph_len);
|
||||
nudph->len = htons(sizeof(struct udphdr) + data_len);
|
||||
|
||||
|
||||
udp_fail_packet(type.strategy, buf, &dlen, *buflen);
|
||||
|
||||
*buflen = dlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
10
quic.h
10
quic.h
@ -1,6 +1,7 @@
|
||||
#ifndef QUIC_H
|
||||
#define QUIC_H
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -125,4 +126,13 @@ int quic_parse_initial_message(uint8_t *inpayload, uint32_t inplen,
|
||||
struct quici_hdr *qhdr,
|
||||
uint8_t **payload, uint32_t *plen);
|
||||
|
||||
// Like fail_packet for TCP
|
||||
int udp_fail_packet(struct udp_failing_strategy strategy, uint8_t *payload, uint32_t *plen, uint32_t avail_buflen);
|
||||
|
||||
// Like gen_fake_sni for TCP
|
||||
int gen_fake_udp(struct udp_fake_type type,
|
||||
const void *ipxh, uint32_t iph_len,
|
||||
const struct udphdr *udph,
|
||||
uint8_t *buf, uint32_t *buflen);
|
||||
|
||||
#endif /* QUIC_H */
|
||||
|
14
utils.h
14
utils.h
@ -142,6 +142,20 @@ struct fake_type {
|
||||
struct failing_strategy strategy;
|
||||
};
|
||||
|
||||
struct udp_failing_strategy {
|
||||
unsigned int strategy;
|
||||
uint8_t faking_ttl;
|
||||
};
|
||||
|
||||
struct udp_fake_type {
|
||||
uint16_t fake_len;
|
||||
|
||||
// faking strategy of the fake packet.
|
||||
// Does not support bitmask, pass standalone strategy.
|
||||
// Pass 0 if you don't want any faking procedures.
|
||||
struct udp_failing_strategy strategy;
|
||||
};
|
||||
|
||||
/**
|
||||
* Invalidates the raw packet. The function aims to invalid the packet
|
||||
* in such way as it will be accepted by DPI, but dropped by target server
|
||||
|
Loading…
Reference in New Issue
Block a user