mirror of
https://github.com/Waujito/youtubeUnblock.git
synced 2025-12-31 11:45:49 +03:00
UDP faking support
This commit is contained in:
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_PAST_SEQ (1 << 2)
|
||||||
#define FAKE_STRAT_TCP_CHECK (1 << 3)
|
#define FAKE_STRAT_TCP_CHECK (1 << 3)
|
||||||
#define FAKE_STRAT_TCP_MD5SUM (1 << 4)
|
#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.
|
* 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verdict == PKT_CONTINUE)
|
if (verdict == PKT_CONTINUE) {
|
||||||
|
lgtrace_addp("continue_flow");
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
lgtrace_end();
|
goto ret_verdict;
|
||||||
return verdict;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
accept:
|
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();
|
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) {
|
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:
|
continue_flow:
|
||||||
lgtrace_addp("continue_flow");
|
|
||||||
return PKT_CONTINUE;
|
return PKT_CONTINUE;
|
||||||
accept:
|
accept:
|
||||||
lgtrace_addp("accept");
|
|
||||||
return PKT_ACCEPT;
|
return PKT_ACCEPT;
|
||||||
drop:
|
drop:
|
||||||
lgtrace_addp("drop");
|
|
||||||
return PKT_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) {
|
if (section->quic_drop) {
|
||||||
lgtrace_addp("QUIC probe");
|
lgtrace_addp("QUIC probe");
|
||||||
const struct quic_lhdr *qch;
|
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");
|
lgtrace_addp("quic initial message");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (1) {
|
if (1) {
|
||||||
lgtrace_addp("Probe udp");
|
for (int i = 0; i < 6; i++) {
|
||||||
if (ipver == IP4VERSION && ntohs(udph->dest) > 30) {
|
NETBUF_ALLOC(fake_udp, MAX_PACKET_SIZE);
|
||||||
lgtrace_addp("udp fool");
|
if (!NETBUF_CHECK(fake_udp)) {
|
||||||
const uint8_t *payload;
|
lgerror(-ENOMEM, "Allocation error");
|
||||||
uint32_t payload_len;
|
return -ENOMEM;
|
||||||
|
|
||||||
uint32_t poses[10];
|
|
||||||
int cnt = 3;
|
|
||||||
|
|
||||||
poses[0] = 8;
|
|
||||||
for (int i = 1; i < cnt; i++) {
|
|
||||||
poses[i] = poses[i - 1] + 8;
|
|
||||||
}
|
}
|
||||||
|
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) {
|
if (ret < 0) {
|
||||||
lgerror("ip4 send frags", ret);
|
lgerror(ret, "gen_fake_udp");
|
||||||
|
goto erret_lc;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
goto accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ret = instance_config.send_raw_packet(pkt, pktlen);
|
||||||
goto drop;
|
goto drop;
|
||||||
} else {
|
|
||||||
lginfo("WARNING: IP fragmentation is supported only for IPv4\n");
|
|
||||||
goto accept;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
continue_flow:
|
continue_flow:
|
||||||
lgtrace_addp("continue_flow");
|
|
||||||
return PKT_CONTINUE;
|
return PKT_CONTINUE;
|
||||||
accept_quic:
|
accept_quic:
|
||||||
accept:
|
accept:
|
||||||
|
|||||||
109
quic.c
109
quic.c
@@ -138,3 +138,112 @@ invalid_packet:
|
|||||||
lgerror(-EINVAL, "QUIC invalid Initial packet");
|
lgerror(-EINVAL, "QUIC invalid Initial packet");
|
||||||
return -EINVAL;
|
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
|
#ifndef QUIC_H
|
||||||
#define QUIC_H
|
#define QUIC_H
|
||||||
#include "types.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,
|
struct quici_hdr *qhdr,
|
||||||
uint8_t **payload, uint32_t *plen);
|
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 */
|
#endif /* QUIC_H */
|
||||||
|
|||||||
14
utils.h
14
utils.h
@@ -142,6 +142,20 @@ struct fake_type {
|
|||||||
struct failing_strategy strategy;
|
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
|
* 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
|
* in such way as it will be accepted by DPI, but dropped by target server
|
||||||
|
|||||||
Reference in New Issue
Block a user