mirror of
https://github.com/hufrea/byedpi.git
synced 2024-12-22 06:15:14 +00:00
two sockets for UDP, ignore dst and proto
This commit is contained in:
parent
15b9f50a5c
commit
4be8bd33f0
52
extend.c
52
extend.c
@ -162,20 +162,6 @@ bool check_proto_tcp(int proto, struct eval *val)
|
||||
}
|
||||
|
||||
|
||||
bool check_proto_udp(int proto, char *buffer, size_t n)
|
||||
{
|
||||
if ((proto & IS_QUIC) &&
|
||||
is_quic_inital(buffer, n)) {
|
||||
return 1;
|
||||
}
|
||||
if ((proto & IS_DNS) &&
|
||||
is_dns_req(buffer, n)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int on_torst(struct poolhd *pool, struct eval *val)
|
||||
{
|
||||
int m = val->pair->attempt + 1;
|
||||
@ -371,41 +357,3 @@ int on_desync(struct poolhd *pool, struct eval *val,
|
||||
val->pair->type = EV_PRE_TUNNEL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ssize_t udp_hook(struct eval *val,
|
||||
char *buffer, size_t n, struct sockaddr_ina *dst)
|
||||
{
|
||||
int m = val->attempt;
|
||||
struct desync_params *dp = ¶ms.dp[m];
|
||||
|
||||
if (val->flag != FLAG_CONN) {
|
||||
if (!m) for (; m < params.dp_count; m++) {
|
||||
dp = ¶ms.dp[m];
|
||||
if ((!dp->proto || check_proto_udp(dp->proto, buffer, n))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m >= params.dp_count) {
|
||||
return -1;
|
||||
}
|
||||
val->attempt = m;
|
||||
val->flag = FLAG_CONN;
|
||||
}
|
||||
|
||||
struct sockaddr_ina addr;
|
||||
if (dp->to_ip) {
|
||||
addr.in6 = dp->addr;
|
||||
if (dst->sa.sa_family == AF_INET6) {
|
||||
map_fix(&addr, 6);
|
||||
}
|
||||
else {
|
||||
map_fix(&addr, 0);
|
||||
}
|
||||
if (!addr.in.sin_port) {
|
||||
addr.in.sin_port = dst->in.sin_port;
|
||||
}
|
||||
dst = &addr;
|
||||
}
|
||||
return sendto(val->fd, buffer, n, 0, &dst->sa, sizeof(*dst));
|
||||
}
|
||||
|
3
extend.h
3
extend.h
@ -6,6 +6,3 @@ int on_tunnel_check(struct poolhd *pool, struct eval *val,
|
||||
|
||||
int on_desync(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize);
|
||||
|
||||
ssize_t udp_hook(struct eval *val,
|
||||
char *buffer, size_t n, struct sockaddr_ina *dst);
|
45
main.c
45
main.c
@ -56,6 +56,9 @@ struct params params = {
|
||||
.baddr = {
|
||||
.sin6_family = AF_INET6
|
||||
},
|
||||
.laddr = {
|
||||
.sin6_family = AF_INET
|
||||
},
|
||||
.debug = 0
|
||||
};
|
||||
|
||||
@ -81,7 +84,7 @@ const char help_text[] = {
|
||||
#ifdef TIMEOUT_SUPPORT
|
||||
" -T, --timeout <sec> Timeout waiting for response, after which trigger auto\n"
|
||||
#endif
|
||||
" -K, --proto[=t,h,d,q] Protocol whitelist: tls,http,dns,quic\n"
|
||||
" -K, --proto[=t,h] Protocol whitelist: tls,http\n"
|
||||
" -H, --hosts <file|:str> Hosts whitelist\n"
|
||||
" -D, --dst <ip[:port]> Custom destination IP\n"
|
||||
" -s, --split <n[+s]> Split packet at n\n"
|
||||
@ -280,10 +283,13 @@ int get_addr(const char *str, struct sockaddr_ina *addr)
|
||||
if (getaddrinfo(str, 0, &hints, &res) || !res) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (res->ai_addr->sa_family == AF_INET6)
|
||||
addr->in6 = *(struct sockaddr_in6 *)res->ai_addr;
|
||||
addr->in6.sin6_addr = (
|
||||
(struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
|
||||
else
|
||||
addr->in = *(struct sockaddr_in *)res->ai_addr;
|
||||
addr->in.sin_addr = (
|
||||
(struct sockaddr_in *)res->ai_addr)->sin_addr;
|
||||
freeaddrinfo(res);
|
||||
|
||||
return 0;
|
||||
@ -438,13 +444,6 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
struct sockaddr_ina s = {
|
||||
.in = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons(1080)
|
||||
}},
|
||||
b = { .in6 = params.baddr };
|
||||
|
||||
int optc = sizeof(options)/sizeof(*options);
|
||||
for (int i = 0, e = optc; i < e; i++)
|
||||
optc += options[i].has_arg;
|
||||
@ -459,6 +458,8 @@ int main(int argc, char **argv)
|
||||
opt[o] = ':';
|
||||
}
|
||||
}
|
||||
|
||||
params.laddr.sin6_port = htons(1080);
|
||||
|
||||
int rez;
|
||||
int invalid = 0;
|
||||
@ -466,8 +467,6 @@ int main(int argc, char **argv)
|
||||
long val = 0;
|
||||
char *end = 0;
|
||||
|
||||
uint16_t port = htons(1080);
|
||||
|
||||
struct desync_params *dp = add((void *)¶ms.dp,
|
||||
¶ms.dp_count, sizeof(struct desync_params));
|
||||
if (!dp) {
|
||||
@ -499,7 +498,8 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
|
||||
case 'i':
|
||||
if (get_addr(optarg, &s) < 0)
|
||||
if (get_addr(optarg,
|
||||
(struct sockaddr_ina *)¶ms.laddr) < 0)
|
||||
invalid = 1;
|
||||
break;
|
||||
|
||||
@ -508,14 +508,13 @@ int main(int argc, char **argv)
|
||||
if (val <= 0 || val > 0xffff || *end)
|
||||
invalid = 1;
|
||||
else
|
||||
port = htons(val);
|
||||
params.laddr.sin6_port = htons(val);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
if (get_addr(optarg, &b) < 0)
|
||||
if (get_addr(optarg,
|
||||
(struct sockaddr_ina *)¶ms.baddr) < 0)
|
||||
invalid = 1;
|
||||
else
|
||||
params.baddr = b.in6;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
@ -625,12 +624,6 @@ int main(int argc, char **argv)
|
||||
case 'h':
|
||||
dp->proto |= IS_HTTP;
|
||||
break;
|
||||
case 'd':
|
||||
dp->proto |= IS_DNS;
|
||||
break;
|
||||
case 'q':
|
||||
dp->proto |= IS_QUIC;
|
||||
break;
|
||||
default:
|
||||
invalid = 1;
|
||||
continue;
|
||||
@ -821,10 +814,8 @@ int main(int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
s.in.sin_port = port;
|
||||
b.in.sin_port = 0;
|
||||
|
||||
if (b.sa.sa_family != AF_INET6) {
|
||||
if (params.laddr.sin6_family != AF_INET6) {
|
||||
params.ipv6 = 0;
|
||||
}
|
||||
if (!params.def_ttl) {
|
||||
@ -839,7 +830,7 @@ int main(int argc, char **argv)
|
||||
clear_params();
|
||||
return -1;
|
||||
}
|
||||
int status = run(&s);
|
||||
int status = run((struct sockaddr_ina *)¶ms.laddr);
|
||||
clear_params();
|
||||
return status;
|
||||
}
|
||||
|
@ -350,7 +350,7 @@ bool is_tls_alert(char *resp, size_t sn) {
|
||||
&& !memcmp(resp, "\x15\x03\x01\x00\x02\x02", 6));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
bool is_dns_req(char *buffer, size_t n)
|
||||
{
|
||||
if (n < 12) {
|
||||
@ -364,7 +364,7 @@ bool is_quic_inital(char *buffer, size_t bsize)
|
||||
{
|
||||
return (bsize > 64 && (buffer[0] & 0xc0) == 0xc0);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
int mod_http(char *buffer, size_t bsize, int m)
|
||||
{
|
||||
|
@ -6,8 +6,8 @@
|
||||
#define IS_UNKNOWN 0
|
||||
#define IS_HTTP 1
|
||||
#define IS_HTTPS 2
|
||||
#define IS_QUIC 4
|
||||
#define IS_DNS 8
|
||||
//#define IS_QUIC 4
|
||||
//#define IS_DNS 8
|
||||
|
||||
#define MH_HMIX 1
|
||||
#define MH_SPACE 2
|
||||
@ -38,6 +38,6 @@ bool is_tls_alert(char *resp, size_t sn);
|
||||
|
||||
int part_tls(char *buffer, size_t bsize, ssize_t n, long pos);
|
||||
|
||||
bool is_dns_req(char *buffer, size_t n);
|
||||
//bool is_dns_req(char *buffer, size_t n);
|
||||
|
||||
bool is_quic_inital(char *buffer, size_t bsize);
|
||||
//bool is_quic_inital(char *buffer, size_t bsize);
|
||||
|
1
params.h
1
params.h
@ -91,6 +91,7 @@ struct params {
|
||||
int debug;
|
||||
size_t bfsize;
|
||||
struct sockaddr_in6 baddr;
|
||||
struct sockaddr_in6 laddr;
|
||||
struct mphdr *mempool;
|
||||
};
|
||||
|
||||
|
95
proxy.c
95
proxy.c
@ -64,9 +64,6 @@ void map_fix(struct sockaddr_ina *addr, char f6)
|
||||
static inline char addr_equ(
|
||||
struct sockaddr_ina *a, struct sockaddr_ina *b)
|
||||
{
|
||||
if (a->in.sin_port != b->in.sin_port) {
|
||||
return 0;
|
||||
}
|
||||
if (a->sa.sa_family == AF_INET) {
|
||||
return
|
||||
*((uint32_t *)(&a->in.sin_addr)) ==
|
||||
@ -398,7 +395,8 @@ int create_conn(struct poolhd *pool,
|
||||
int udp_associate(struct poolhd *pool,
|
||||
struct eval *val, struct sockaddr_ina *dst)
|
||||
{
|
||||
struct sockaddr_ina addr = {};
|
||||
struct sockaddr_ina addr = { .in6 = params.laddr };
|
||||
addr.in.sin_port = 0;
|
||||
|
||||
int ufd = nb_socket(params.baddr.sin6_family, SOCK_DGRAM);
|
||||
if (ufd < 0) {
|
||||
@ -420,21 +418,44 @@ int udp_associate(struct poolhd *pool,
|
||||
close(ufd);
|
||||
return -1;
|
||||
}
|
||||
socklen_t sz = sizeof(addr);
|
||||
if (getsockname(ufd, &addr.sa, &sz)) {
|
||||
perror("getsockname");
|
||||
close(ufd);
|
||||
return -1;
|
||||
}
|
||||
struct eval *pair = add_event(pool, EV_UDP_TUNNEL, ufd, POLLIN);
|
||||
if (!pair) {
|
||||
close(ufd);
|
||||
return -1;
|
||||
}
|
||||
val->pair = pair;
|
||||
pair->pair = val;
|
||||
pair->in6.sin6_port = 0;
|
||||
|
||||
int cfd = nb_socket(addr.sa.sa_family, SOCK_DGRAM);
|
||||
if (cfd < 0) {
|
||||
perror("socket");
|
||||
del_event(pool, pair);
|
||||
return -1;
|
||||
}
|
||||
if (bind(cfd, &addr.sa, sizeof(addr)) < 0) {
|
||||
uniperror("bind");
|
||||
del_event(pool, pair);
|
||||
close(cfd);
|
||||
return -1;
|
||||
}
|
||||
struct eval *client = add_event(pool, EV_UDP_TUNNEL, cfd, POLLIN);
|
||||
if (!pair) {
|
||||
del_event(pool, pair);
|
||||
close(cfd);
|
||||
return -1;
|
||||
}
|
||||
val->type = EV_IGNORE;
|
||||
val->pair = client;
|
||||
client->pair = pair;
|
||||
pair->pair = val;
|
||||
|
||||
client->flag = FLAG_CONN;
|
||||
client->in6 = val->in6;
|
||||
client->in6.sin6_port = 0;
|
||||
|
||||
socklen_t sz = sizeof(addr);
|
||||
if (getsockname(cfd, &addr.sa, &sz)) {
|
||||
perror("getsockname");
|
||||
return -1;
|
||||
}
|
||||
struct s5_req s5r = {
|
||||
.ver = 0x05
|
||||
};
|
||||
@ -573,55 +594,61 @@ int on_tunnel(struct poolhd *pool, struct eval *val,
|
||||
|
||||
int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize)
|
||||
{
|
||||
char *data = buffer + S_SIZE_I6;
|
||||
size_t data_len = bfsize - S_SIZE_I6;
|
||||
char *data = buffer;
|
||||
size_t data_len = bfsize;
|
||||
|
||||
if (val->flag != FLAG_CONN) {
|
||||
data += S_SIZE_I6;
|
||||
data_len -= S_SIZE_I6;
|
||||
}
|
||||
struct sockaddr_ina addr = {0};
|
||||
|
||||
do {
|
||||
struct sockaddr_ina addr = {0};
|
||||
struct sockaddr_ina *src = (struct sockaddr_ina *)&val->in6;
|
||||
socklen_t asz = sizeof(addr);
|
||||
|
||||
ssize_t n = recvfrom(val->fd, data, data_len, 0, &addr.sa, &asz);
|
||||
ssize_t n = recvfrom(val->fd, data, data_len, 0, &addr.sa, &asz);
|
||||
if (n < 1) {
|
||||
if (n && errno == EAGAIN)
|
||||
break;
|
||||
perror("recv udp");
|
||||
return -1;
|
||||
}
|
||||
if (!src->in.sin_port) {
|
||||
src->in6 = addr.in6;
|
||||
}
|
||||
ssize_t ns = 0;
|
||||
ssize_t ns;
|
||||
|
||||
if (addr_equ(src, &addr)) {
|
||||
if (val->flag == FLAG_CONN) {
|
||||
if (!val->in6.sin6_port) {
|
||||
if (connect(val->fd, &addr.sa, sizeof(addr)) < 0) {
|
||||
uniperror("connect");
|
||||
return -1;
|
||||
}
|
||||
val->in6 = addr.in6;
|
||||
}
|
||||
if (*(data + 2) != 0) { // frag
|
||||
continue;
|
||||
}
|
||||
int offs = s5_get_addr(data, n, &addr, SOCK_DGRAM);
|
||||
if (offs < 0) {
|
||||
LOG(LOG_E, "udp parse error\n");
|
||||
return -1;
|
||||
}
|
||||
val->pair->in6 = addr.in6;
|
||||
|
||||
if (src->sa.sa_family == AF_INET6) {
|
||||
if (params.baddr.sin6_family == AF_INET6) {
|
||||
map_fix(&addr, 6);
|
||||
}
|
||||
if (src->sa.sa_family != addr.sa.sa_family) {
|
||||
if (params.baddr.sin6_family != addr.sa.sa_family) {
|
||||
return -1;
|
||||
}
|
||||
ns = udp_hook(val,
|
||||
data + offs, n - offs, &addr);
|
||||
ns = sendto(val->pair->fd,
|
||||
data + offs, n - offs, 0, &addr.sa, sizeof(addr));
|
||||
}
|
||||
else {
|
||||
//map_fix(&addr, 0);
|
||||
map_fix(&addr, 0);
|
||||
memset(buffer, 0, S_SIZE_I6);
|
||||
|
||||
int offs = s5_set_addr(data, S_SIZE_I6,
|
||||
(struct sockaddr_ina *)&val->pair->in6, 1);
|
||||
int offs = s5_set_addr(data, S_SIZE_I6, &addr, 1);
|
||||
if (offs < 0 || offs > S_SIZE_I6) {
|
||||
return -1;
|
||||
}
|
||||
ns = sendto(val->fd, data - offs, offs + n, 0,
|
||||
(struct sockaddr *)&val->in6, sizeof(val->in6));
|
||||
ns = send(val->pair->pair->fd, data - offs, offs + n, 0);
|
||||
}
|
||||
if (ns < 0) {
|
||||
perror("sendto");
|
||||
|
@ -74,8 +74,8 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
|
||||
В Linux переводится в миллисекунды, поэтому можно указать дробное число
|
||||
Истечение таймаута будет обработано --auto
|
||||
|
||||
-K, --proto[=t,h,d,q]
|
||||
Белый список протоколов: tls,http,dns,quic
|
||||
-K, --proto[=t,h]
|
||||
Белый список протоколов: tls,http
|
||||
|
||||
-H, --hosts <file|:string>
|
||||
Ограничить область действия параметров списком доменов
|
||||
|
Loading…
Reference in New Issue
Block a user