mirror of
https://github.com/hufrea/byedpi.git
synced 2024-12-22 06:15:14 +00:00
Delete UDP support
This commit is contained in:
parent
ad697d9abd
commit
391dd8e758
8
conev.h
8
conev.h
@ -24,8 +24,7 @@ enum eid {
|
||||
EV_REQUEST,
|
||||
EV_CONNECT,
|
||||
EV_IGNORE,
|
||||
EV_TUNNEL,
|
||||
EV_UDP_TUNNEL
|
||||
EV_TUNNEL
|
||||
};
|
||||
|
||||
#define FLAG_S4 1
|
||||
@ -38,8 +37,7 @@ char *eid_name[] = {
|
||||
"EV_REQUEST",
|
||||
"EV_CONNECT",
|
||||
"EV_IGNORE",
|
||||
"EV_TUNNEL",
|
||||
"EV_UDP_TUNNEL"
|
||||
"EV_TUNNEL"
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -86,4 +84,4 @@ void destroy_pool(struct poolhd *pool);
|
||||
|
||||
struct eval *next_event(struct poolhd *pool, int *offs, int *type);
|
||||
|
||||
int mod_etype(struct poolhd *pool, struct eval *val, int type, char rm);
|
||||
int mod_etype(struct poolhd *pool, struct eval *val, int type, char rm);
|
||||
|
29
desync.c
29
desync.c
@ -197,32 +197,3 @@ int desync(int sfd, char *buffer,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int desync_udp(int fd, char *buffer,
|
||||
ssize_t n, struct sockaddr *dst)
|
||||
{
|
||||
int fa = get_family(dst);
|
||||
socklen_t s = dst->sa_family == AF_INET6 ?
|
||||
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
|
||||
|
||||
if (params.desync_udp & DESYNC_UDP_FAKE) {
|
||||
if (setttl(fd, params.ttl, fa) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (sendto(fd, fake_udp.data,
|
||||
fake_udp.size, 0, dst, s) < 0) {
|
||||
perror("sendto");
|
||||
return -1;
|
||||
}
|
||||
if (setttl(fd, params.def_ttl, fa) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ssize_t ns = sendto(fd, buffer, n, 0, dst, s);
|
||||
if (ns < 0) {
|
||||
perror("sendto");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
1
desync.h
1
desync.h
@ -1,2 +1 @@
|
||||
int desync(int sfd, char *buffer, ssize_t n, struct sockaddr *dst);
|
||||
int desync_udp(int fd, char *buffer, ssize_t n, struct sockaddr *dst);
|
31
main.c
31
main.c
@ -26,9 +26,6 @@ struct packet fake_tls = {
|
||||
},
|
||||
fake_http = {
|
||||
sizeof(http_data), http_data
|
||||
},
|
||||
fake_udp = {
|
||||
sizeof(udp_data), udp_data
|
||||
};
|
||||
|
||||
|
||||
@ -37,7 +34,6 @@ struct params params = {
|
||||
.split = 3,
|
||||
.sfdelay = 3000,
|
||||
.attack = DESYNC_NONE,
|
||||
.desync_udp = 0,
|
||||
.split_host = 0,
|
||||
.def_ttl = 0,
|
||||
.mod_http = 0,
|
||||
@ -45,7 +41,6 @@ struct params params = {
|
||||
|
||||
.ipv6 = 1,
|
||||
.resolve = 1,
|
||||
.udp = 1,
|
||||
.max_open = 512,
|
||||
.bfsize = 16384,
|
||||
.nodelay = 1,
|
||||
@ -65,7 +60,6 @@ const char help_text[] = {
|
||||
" -f, --pidfile <file> Write pid to file\n"
|
||||
" -c, --max-conn <count> Connection count limit, default 512\n"
|
||||
" -N, --no-domain Deny domain resolving\n"
|
||||
" -U, --no-udp Deny UDP associate\n"
|
||||
" -I --conn-ip <ip> Connection binded IP, default ::\n"
|
||||
" -b, --bfs <size> Buffer size, default 16384\n"
|
||||
//" -L, --nodelay <0 or 1> Set TCP_NODELAY option\n"
|
||||
@ -84,12 +78,10 @@ const char help_text[] = {
|
||||
#ifdef FAKE_SUPPORT
|
||||
" -t, --ttl <num> TTL of fake packets, default 8\n"
|
||||
" -l, --fake-tls <file>\n"
|
||||
" -o, --fake-http <file>\n"
|
||||
" -e, --fake-udp <file> Set custom fake packet\n"
|
||||
" -o, --fake-http <file> Set custom fake packet\n"
|
||||
" -n, --tls-sni <str> Change SNI in fake CH\n"
|
||||
#endif
|
||||
" -M, --mod-http <h,d,r> Modify http: hcsmix,dcsmix,rmspace\n"
|
||||
" -u, --desync-udp <f> UDP desync method: fake\n"
|
||||
};
|
||||
|
||||
|
||||
@ -97,7 +89,6 @@ const struct option options[] = {
|
||||
{"daemon", 0, 0, 'D'},
|
||||
{"no-domain", 0, 0, 'N'},
|
||||
{"no-ipv6", 0, 0, 'X'},
|
||||
{"no-udp", 0, 0, 'U'},
|
||||
{"help", 0, 0, 'h'},
|
||||
{"version", 0, 0, 'v'},
|
||||
{"pidfile", 1, 0, 'f'},
|
||||
@ -119,11 +110,9 @@ const struct option options[] = {
|
||||
#ifdef FAKE_SUPPORT
|
||||
{"fake-tls", 1, 0, 'l'},
|
||||
{"fake-http", 1, 0, 'o'},
|
||||
{"fake-udp", 1, 0, 'e'},
|
||||
{"tls-sni", 1, 0, 'n'},
|
||||
#endif
|
||||
{"mod-http", 1, 0, 'M'},
|
||||
{"desync-udp", 1, 0, 'u'},
|
||||
{"global-ttl", 1, 0, 'g'}, //
|
||||
{"delay", 1, 0, 'w'}, //
|
||||
|
||||
@ -251,9 +240,6 @@ int main(int argc, char **argv)
|
||||
case 'X':
|
||||
params.ipv6 = 0;
|
||||
break;
|
||||
case 'U':
|
||||
params.udp = 0;
|
||||
break;
|
||||
case 'h':
|
||||
printf(help_text);
|
||||
return 0;
|
||||
@ -400,14 +386,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
fake_udp.data = ftob(optarg, &fake_udp.size);
|
||||
if (!fake_udp.data) {
|
||||
perror("read file");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
end = optarg;
|
||||
while (end && !invalid) {
|
||||
@ -430,13 +408,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
if (*optarg != 'f')
|
||||
invalid = 1;
|
||||
else
|
||||
params.desync_udp = DESYNC_UDP_FAKE;
|
||||
break;
|
||||
|
||||
case 'g': //
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || val > 255 || *end)
|
||||
|
@ -47,8 +47,6 @@ char http_data[43] = {
|
||||
"Host: www.wikipedia.org\r\n\r\n"
|
||||
};
|
||||
|
||||
char udp_data[64] = {0};
|
||||
|
||||
|
||||
int find_tls_ext_offset(uint16_t type, char *data, size_t size)
|
||||
{
|
||||
@ -213,4 +211,4 @@ int mod_http(char *buffer, size_t bsize, int m)
|
||||
memset(par + 5 + hlen, '\t', sc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
extern char tls_data[517];
|
||||
extern char http_data[43];
|
||||
extern char udp_data[64];
|
||||
|
||||
int change_tls_sni(char *host, char *buffer, size_t bsize);
|
||||
|
||||
@ -19,4 +18,4 @@ int parse_tls(char *buffer, size_t bsize, char **hs);
|
||||
|
||||
int parse_http(char *buffer, size_t bsize, char **hs, uint16_t *port);
|
||||
|
||||
int mod_http(char *buffer, size_t bsize, int m);
|
||||
int mod_http(char *buffer, size_t bsize, int m);
|
||||
|
5
params.h
5
params.h
@ -8,22 +8,18 @@ enum demode {
|
||||
DESYNC_FAKE
|
||||
};
|
||||
|
||||
#define DESYNC_UDP_FAKE 1
|
||||
|
||||
struct params {
|
||||
char de_known;
|
||||
int ttl;
|
||||
int split;
|
||||
size_t sfdelay;
|
||||
enum demode attack;
|
||||
int desync_udp;
|
||||
char split_host;
|
||||
int def_ttl;
|
||||
int mod_http;
|
||||
|
||||
char ipv6;
|
||||
char resolve;
|
||||
char udp;
|
||||
int max_open;
|
||||
int debug;
|
||||
size_t bfsize;
|
||||
@ -41,7 +37,6 @@ struct packet {
|
||||
};
|
||||
extern struct packet fake_tls;
|
||||
extern struct packet fake_http;
|
||||
extern struct packet fake_udp;
|
||||
|
||||
#define LOG_S 1
|
||||
#define LOG_L 2
|
||||
|
246
proxy.c
246
proxy.c
@ -28,22 +28,6 @@ static void on_cancel(int sig) {
|
||||
}
|
||||
|
||||
|
||||
static inline int ip_equ(
|
||||
struct sockaddr_ina *a, struct sockaddr_ina *b)
|
||||
{
|
||||
if (a->sa.sa_family == AF_INET) {
|
||||
return
|
||||
*((uint32_t *)(&a->in.sin_addr)) ==
|
||||
*((uint32_t *)(&b->in.sin_addr));
|
||||
}
|
||||
return
|
||||
*((uint64_t *)(&a->in6.sin6_addr)) ==
|
||||
*((uint64_t *)(&b->in6.sin6_addr)) &&
|
||||
*((uint64_t *)(&a->in6.sin6_addr) + 1) ==
|
||||
*((uint64_t *)(&b->in6.sin6_addr) + 1);
|
||||
}
|
||||
|
||||
|
||||
void map_fix(struct sockaddr_ina *addr, char f6)
|
||||
{
|
||||
struct {
|
||||
@ -115,11 +99,11 @@ int setopts(int fd)
|
||||
|
||||
|
||||
int resolve(char *host, int len,
|
||||
struct sockaddr_ina *addr, int type)
|
||||
struct sockaddr_ina *addr)
|
||||
{
|
||||
struct addrinfo hints = {0}, *res = 0;
|
||||
|
||||
hints.ai_socktype = type;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
hints.ai_family = params.ipv6 ? AF_UNSPEC : AF_INET;
|
||||
|
||||
@ -219,7 +203,7 @@ int handle_socks4(int fd, char *bf,
|
||||
int len = (bf + n - ie) - 2;
|
||||
if (len < 3)
|
||||
break;
|
||||
if (resolve(ie + 1, len, dst, SOCK_STREAM)) {
|
||||
if (resolve(ie + 1, len, dst)) {
|
||||
fprintf(stderr, "not resolved: %.*s\n", len, ie + 1);
|
||||
break;
|
||||
}
|
||||
@ -240,7 +224,7 @@ int handle_socks4(int fd, char *bf,
|
||||
|
||||
|
||||
int s_get_addr(char *buffer, ssize_t n,
|
||||
struct sockaddr_ina *addr, int type)
|
||||
struct sockaddr_ina *addr)
|
||||
{
|
||||
struct s5_req *r = (struct s5_req *)buffer;
|
||||
|
||||
@ -249,7 +233,7 @@ int s_get_addr(char *buffer, ssize_t n,
|
||||
(r->atp == S_ATP_I6 ? S_SIZE_I6 : 0)));
|
||||
if (n < o) {
|
||||
fprintf(stderr, "ss: bad request\n");
|
||||
return -S_ER_GEN;
|
||||
return S_ER_GEN;
|
||||
}
|
||||
switch (r->atp) {
|
||||
case S_ATP_I4:
|
||||
@ -259,58 +243,25 @@ int s_get_addr(char *buffer, ssize_t n,
|
||||
|
||||
case S_ATP_ID:
|
||||
if (!params.resolve) {
|
||||
return -S_ER_ATP;
|
||||
return S_ER_ATP;
|
||||
}
|
||||
if (r->id.len == 1 && type == SOCK_DGRAM) {
|
||||
addr->in.sin_family = AF_INET;
|
||||
LOG(LOG_S, "domain len=1\n");
|
||||
}
|
||||
else if (resolve(r->id.domain, r->id.len, addr, type)) {
|
||||
if (r->id.len < 3 ||
|
||||
resolve(r->id.domain, r->id.len, addr)) {
|
||||
fprintf(stderr, "not resolved: %.*s\n", r->id.len, r->id.domain);
|
||||
return -S_ER_HOST;
|
||||
return S_ER_HOST;
|
||||
}
|
||||
break;
|
||||
|
||||
case S_ATP_I6:
|
||||
if (!params.ipv6)
|
||||
return -S_ER_ATP;
|
||||
return S_ER_ATP;
|
||||
else {
|
||||
addr->in6.sin6_family = AF_INET6;
|
||||
addr->in6.sin6_addr = r->i6;
|
||||
}
|
||||
}
|
||||
addr->in.sin_port = *(uint16_t *)&buffer[o - 2];
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
int s_set_addr(char *buffer, ssize_t n,
|
||||
struct sockaddr_ina *addr, char end)
|
||||
{
|
||||
struct s5_req *r = (struct s5_req *)buffer;
|
||||
if (n < S_SIZE_I4) {
|
||||
return -1;
|
||||
}
|
||||
if (addr->sa.sa_family == AF_INET) {
|
||||
if (end) {
|
||||
r = (struct s5_req *)(buffer - S_SIZE_I4);
|
||||
}
|
||||
r->atp = S_ATP_I4;
|
||||
r->i4 = addr->in.sin_addr;
|
||||
r->p4 = addr->in.sin_port;
|
||||
return S_SIZE_I4;
|
||||
} else {
|
||||
if (n < S_SIZE_I6) {
|
||||
return -1;
|
||||
}
|
||||
if (end) {
|
||||
r = (struct s5_req *)(buffer - S_SIZE_I6);
|
||||
}
|
||||
r->atp = S_ATP_I6;
|
||||
r->i6 = addr->in6.sin6_addr;
|
||||
r->p6 = addr->in6.sin6_port;
|
||||
return S_SIZE_I6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -374,83 +325,11 @@ int create_conn(struct poolhd *pool,
|
||||
}
|
||||
|
||||
|
||||
int udp_asc(struct poolhd *pool,
|
||||
struct eval *val, struct sockaddr_ina *dst)
|
||||
{
|
||||
struct sockaddr_ina bnda = {
|
||||
.sa = {.sa_family = dst->sa.sa_family}}, dsta = {0};
|
||||
socklen_t asz = sizeof(bnda);
|
||||
|
||||
int ip_not_set = ip_equ(&bnda, dst);
|
||||
bnda.in6 = params.baddr;
|
||||
|
||||
if (ip_not_set) {
|
||||
dsta.in6 = val->in6;
|
||||
dsta.in.sin_port = dst->in.sin_port;
|
||||
} else {
|
||||
dsta.in6 = dst->in6;
|
||||
}
|
||||
|
||||
if (bnda.sa.sa_family == AF_INET6) {
|
||||
map_fix(&dsta, 6);
|
||||
}
|
||||
if (dsta.sa.sa_family == AF_INET6) {
|
||||
map_fix(&bnda, 6);
|
||||
}
|
||||
|
||||
int ufd = nb_socket(bnda.sa.sa_family, SOCK_DGRAM);
|
||||
if (ufd < 0) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
if (bnda.sa.sa_family == AF_INET6) {
|
||||
int no = 0;
|
||||
if (setsockopt(ufd, IPPROTO_IPV6,
|
||||
IPV6_V6ONLY, (char *)&no, sizeof(no))) {
|
||||
perror("setsockopt IPV6_V6ONLY");
|
||||
close(ufd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (bind(ufd, &bnda.sa, sizeof(bnda)) < 0) {
|
||||
perror("bind");
|
||||
close(ufd);
|
||||
return -1;
|
||||
}
|
||||
if (getsockname(ufd, &bnda.sa, &asz)) {
|
||||
perror("getsockname");
|
||||
close(ufd);
|
||||
return -1;
|
||||
}
|
||||
struct eval *upair = add_event(pool, EV_UDP_TUNNEL, ufd, POLLIN);
|
||||
if (!upair) {
|
||||
close(ufd);
|
||||
return -1;
|
||||
}
|
||||
val->pair = upair;
|
||||
upair->pair = val;
|
||||
upair->in6 = dsta.in6;
|
||||
|
||||
struct s5_req s5r = {
|
||||
.ver = 0x05
|
||||
};
|
||||
int offs = s_set_addr((char *)&s5r, sizeof(s5r), &bnda, 0);
|
||||
if (offs < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (send(val->fd, (char *)&s5r, offs, 0) < 0) {
|
||||
perror("send");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int on_request(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize)
|
||||
{
|
||||
struct sockaddr_ina dst = {0};
|
||||
int error = 0, offs_e = 0;
|
||||
int error = 0, s5e = 0;
|
||||
|
||||
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
||||
if (n < 1) {
|
||||
@ -471,25 +350,15 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
|
||||
}
|
||||
struct s5_req *r = (struct s5_req *)buffer;
|
||||
|
||||
switch (r->cmd) {
|
||||
case S_CMD_CONN:
|
||||
offs_e = s_get_addr(buffer, n, &dst, SOCK_STREAM);
|
||||
if (offs_e > 0) {
|
||||
error = create_conn(pool, val, &dst);
|
||||
}
|
||||
break;
|
||||
case S_CMD_AUDP:
|
||||
offs_e = s_get_addr(buffer, n, &dst, SOCK_DGRAM);
|
||||
if (offs_e <= 0) {
|
||||
break;
|
||||
}
|
||||
if (params.udp) {
|
||||
error = udp_asc(pool, val, &dst);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(stderr, "ss: unsupported cmd: 0x%x\n", r->cmd);
|
||||
offs_e = -S_ER_CMD;
|
||||
if (r->cmd != S_CMD_CONN) {
|
||||
fprintf(stderr, "ss: unsupported cmd: 0x%x\n", r->cmd);
|
||||
s5e = S_ER_CMD;
|
||||
}
|
||||
else {
|
||||
s5e = s_get_addr(buffer, n, &dst);
|
||||
if (!s5e) {
|
||||
error = create_conn(pool, val, &dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*buffer == S_VER4) {
|
||||
@ -503,8 +372,8 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
|
||||
fprintf(stderr, "ss: invalid version: 0x%x (%lu)\n", *buffer, n);
|
||||
return -1;
|
||||
}
|
||||
if (error || offs_e < 0) {
|
||||
if (resp_error(val->fd, errno, val->flag, -offs_e) < 0)
|
||||
if (error || s5e) {
|
||||
if (resp_error(val->fd, error ? errno : 0, val->flag, s5e) < 0)
|
||||
perror("send");
|
||||
return -1;
|
||||
}
|
||||
@ -658,70 +527,6 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
||||
}
|
||||
|
||||
|
||||
int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize)
|
||||
{
|
||||
int skip = S_SIZE_I6, offs;
|
||||
do {
|
||||
struct sockaddr_ina addr = {0};
|
||||
struct sockaddr_ina *dst = (struct sockaddr_ina *)&val->in6;
|
||||
socklen_t asz = sizeof(addr);
|
||||
|
||||
ssize_t n = recvfrom(val->fd, buffer + skip,
|
||||
bfsize - skip, 0, &addr.sa, &asz), ns;
|
||||
|
||||
if (n < 0 && errno == EAGAIN)
|
||||
break;
|
||||
if (n < 1) {
|
||||
perror("recv udp");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!dst->in.sin_port) {
|
||||
dst->in.sin_port = addr.in.sin_port;
|
||||
}
|
||||
|
||||
if (ip_equ(dst, &addr) && dst->in.sin_port == addr.in.sin_port) {
|
||||
if (buffer[skip + 2]) { // frag
|
||||
continue;
|
||||
}
|
||||
offs = s_get_addr(buffer + skip, n, &addr, SOCK_DGRAM);
|
||||
if (offs < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (dst->in.sin_family == AF_INET6) {
|
||||
map_fix(&addr, 6);
|
||||
}
|
||||
if (dst->in.sin_family != addr.sa.sa_family) {
|
||||
return -1;
|
||||
}
|
||||
if (val->flag == FLAG_CONN)
|
||||
ns = sendto(val->fd,
|
||||
buffer + skip + offs, n - offs, 0, &addr.sa, asz);
|
||||
else {
|
||||
ns = desync_udp(val->fd,
|
||||
buffer + skip + offs, n - offs, &addr.sa);
|
||||
val->flag = FLAG_CONN;
|
||||
}
|
||||
} else {
|
||||
map_fix(&addr, 0);
|
||||
|
||||
offs = s_set_addr(buffer + skip, skip, &addr, 1);
|
||||
if (offs < 0 || offs > skip) {
|
||||
return -1;
|
||||
}
|
||||
memset(buffer + skip - offs, 0, 3);
|
||||
ns = sendto(val->fd, buffer + skip - offs,
|
||||
n + offs, 0, (struct sockaddr *)&val->in6, sizeof(val->in6));
|
||||
}
|
||||
if (ns < 0) {
|
||||
perror("sendto");
|
||||
return -1;
|
||||
}
|
||||
} while(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int big_loop(int srvfd)
|
||||
{
|
||||
size_t bfsize = params.bfsize;
|
||||
@ -776,11 +581,6 @@ int big_loop(int srvfd)
|
||||
del_event(pool, val);
|
||||
continue;
|
||||
|
||||
case EV_UDP_TUNNEL:
|
||||
if (on_udp_tunnel(val, buffer, bfsize))
|
||||
del_event(pool, val);
|
||||
continue;
|
||||
|
||||
case EV_IGNORE:
|
||||
if (etype & (POLLHUP | POLLERR | POLLRDHUP))
|
||||
del_event(pool, val);
|
||||
|
Loading…
Reference in New Issue
Block a user