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