mirror of
https://github.com/hufrea/byedpi.git
synced 2024-12-22 14:25:44 +00:00
Delete UDP support
This commit is contained in:
parent
ad697d9abd
commit
391dd8e758
6
conev.h
6
conev.h
@ -24,8 +24,7 @@ enum eid {
|
|||||||
EV_REQUEST,
|
EV_REQUEST,
|
||||||
EV_CONNECT,
|
EV_CONNECT,
|
||||||
EV_IGNORE,
|
EV_IGNORE,
|
||||||
EV_TUNNEL,
|
EV_TUNNEL
|
||||||
EV_UDP_TUNNEL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FLAG_S4 1
|
#define FLAG_S4 1
|
||||||
@ -38,8 +37,7 @@ char *eid_name[] = {
|
|||||||
"EV_REQUEST",
|
"EV_REQUEST",
|
||||||
"EV_CONNECT",
|
"EV_CONNECT",
|
||||||
"EV_IGNORE",
|
"EV_IGNORE",
|
||||||
"EV_TUNNEL",
|
"EV_TUNNEL"
|
||||||
"EV_UDP_TUNNEL"
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
29
desync.c
29
desync.c
@ -197,32 +197,3 @@ int desync(int sfd, char *buffer,
|
|||||||
}
|
}
|
||||||
return 0;
|
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(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 = {
|
fake_http = {
|
||||||
sizeof(http_data), http_data
|
sizeof(http_data), http_data
|
||||||
},
|
|
||||||
fake_udp = {
|
|
||||||
sizeof(udp_data), udp_data
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -37,7 +34,6 @@ struct params params = {
|
|||||||
.split = 3,
|
.split = 3,
|
||||||
.sfdelay = 3000,
|
.sfdelay = 3000,
|
||||||
.attack = DESYNC_NONE,
|
.attack = DESYNC_NONE,
|
||||||
.desync_udp = 0,
|
|
||||||
.split_host = 0,
|
.split_host = 0,
|
||||||
.def_ttl = 0,
|
.def_ttl = 0,
|
||||||
.mod_http = 0,
|
.mod_http = 0,
|
||||||
@ -45,7 +41,6 @@ struct params params = {
|
|||||||
|
|
||||||
.ipv6 = 1,
|
.ipv6 = 1,
|
||||||
.resolve = 1,
|
.resolve = 1,
|
||||||
.udp = 1,
|
|
||||||
.max_open = 512,
|
.max_open = 512,
|
||||||
.bfsize = 16384,
|
.bfsize = 16384,
|
||||||
.nodelay = 1,
|
.nodelay = 1,
|
||||||
@ -65,7 +60,6 @@ const char help_text[] = {
|
|||||||
" -f, --pidfile <file> Write pid to file\n"
|
" -f, --pidfile <file> Write pid to file\n"
|
||||||
" -c, --max-conn <count> Connection count limit, default 512\n"
|
" -c, --max-conn <count> Connection count limit, default 512\n"
|
||||||
" -N, --no-domain Deny domain resolving\n"
|
" -N, --no-domain Deny domain resolving\n"
|
||||||
" -U, --no-udp Deny UDP associate\n"
|
|
||||||
" -I --conn-ip <ip> Connection binded IP, default ::\n"
|
" -I --conn-ip <ip> Connection binded IP, default ::\n"
|
||||||
" -b, --bfs <size> Buffer size, default 16384\n"
|
" -b, --bfs <size> Buffer size, default 16384\n"
|
||||||
//" -L, --nodelay <0 or 1> Set TCP_NODELAY option\n"
|
//" -L, --nodelay <0 or 1> Set TCP_NODELAY option\n"
|
||||||
@ -84,12 +78,10 @@ const char help_text[] = {
|
|||||||
#ifdef FAKE_SUPPORT
|
#ifdef FAKE_SUPPORT
|
||||||
" -t, --ttl <num> TTL of fake packets, default 8\n"
|
" -t, --ttl <num> TTL of fake packets, default 8\n"
|
||||||
" -l, --fake-tls <file>\n"
|
" -l, --fake-tls <file>\n"
|
||||||
" -o, --fake-http <file>\n"
|
" -o, --fake-http <file> Set custom fake packet\n"
|
||||||
" -e, --fake-udp <file> Set custom fake packet\n"
|
|
||||||
" -n, --tls-sni <str> Change SNI in fake CH\n"
|
" -n, --tls-sni <str> Change SNI in fake CH\n"
|
||||||
#endif
|
#endif
|
||||||
" -M, --mod-http <h,d,r> Modify http: hcsmix,dcsmix,rmspace\n"
|
" -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'},
|
{"daemon", 0, 0, 'D'},
|
||||||
{"no-domain", 0, 0, 'N'},
|
{"no-domain", 0, 0, 'N'},
|
||||||
{"no-ipv6", 0, 0, 'X'},
|
{"no-ipv6", 0, 0, 'X'},
|
||||||
{"no-udp", 0, 0, 'U'},
|
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
{"version", 0, 0, 'v'},
|
{"version", 0, 0, 'v'},
|
||||||
{"pidfile", 1, 0, 'f'},
|
{"pidfile", 1, 0, 'f'},
|
||||||
@ -119,11 +110,9 @@ const struct option options[] = {
|
|||||||
#ifdef FAKE_SUPPORT
|
#ifdef FAKE_SUPPORT
|
||||||
{"fake-tls", 1, 0, 'l'},
|
{"fake-tls", 1, 0, 'l'},
|
||||||
{"fake-http", 1, 0, 'o'},
|
{"fake-http", 1, 0, 'o'},
|
||||||
{"fake-udp", 1, 0, 'e'},
|
|
||||||
{"tls-sni", 1, 0, 'n'},
|
{"tls-sni", 1, 0, 'n'},
|
||||||
#endif
|
#endif
|
||||||
{"mod-http", 1, 0, 'M'},
|
{"mod-http", 1, 0, 'M'},
|
||||||
{"desync-udp", 1, 0, 'u'},
|
|
||||||
{"global-ttl", 1, 0, 'g'}, //
|
{"global-ttl", 1, 0, 'g'}, //
|
||||||
{"delay", 1, 0, 'w'}, //
|
{"delay", 1, 0, 'w'}, //
|
||||||
|
|
||||||
@ -251,9 +240,6 @@ int main(int argc, char **argv)
|
|||||||
case 'X':
|
case 'X':
|
||||||
params.ipv6 = 0;
|
params.ipv6 = 0;
|
||||||
break;
|
break;
|
||||||
case 'U':
|
|
||||||
params.udp = 0;
|
|
||||||
break;
|
|
||||||
case 'h':
|
case 'h':
|
||||||
printf(help_text);
|
printf(help_text);
|
||||||
return 0;
|
return 0;
|
||||||
@ -400,14 +386,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
|
||||||
fake_udp.data = ftob(optarg, &fake_udp.size);
|
|
||||||
if (!fake_udp.data) {
|
|
||||||
perror("read file");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
end = optarg;
|
end = optarg;
|
||||||
while (end && !invalid) {
|
while (end && !invalid) {
|
||||||
@ -430,13 +408,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u':
|
|
||||||
if (*optarg != 'f')
|
|
||||||
invalid = 1;
|
|
||||||
else
|
|
||||||
params.desync_udp = DESYNC_UDP_FAKE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'g': //
|
case 'g': //
|
||||||
val = strtol(optarg, &end, 0);
|
val = strtol(optarg, &end, 0);
|
||||||
if (val <= 0 || val > 255 || *end)
|
if (val <= 0 || val > 255 || *end)
|
||||||
|
@ -47,8 +47,6 @@ char http_data[43] = {
|
|||||||
"Host: www.wikipedia.org\r\n\r\n"
|
"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)
|
int find_tls_ext_offset(uint16_t type, char *data, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
extern char tls_data[517];
|
extern char tls_data[517];
|
||||||
extern char http_data[43];
|
extern char http_data[43];
|
||||||
extern char udp_data[64];
|
|
||||||
|
|
||||||
int change_tls_sni(char *host, char *buffer, size_t bsize);
|
int change_tls_sni(char *host, char *buffer, size_t bsize);
|
||||||
|
|
||||||
|
5
params.h
5
params.h
@ -8,22 +8,18 @@ enum demode {
|
|||||||
DESYNC_FAKE
|
DESYNC_FAKE
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DESYNC_UDP_FAKE 1
|
|
||||||
|
|
||||||
struct params {
|
struct params {
|
||||||
char de_known;
|
char de_known;
|
||||||
int ttl;
|
int ttl;
|
||||||
int split;
|
int split;
|
||||||
size_t sfdelay;
|
size_t sfdelay;
|
||||||
enum demode attack;
|
enum demode attack;
|
||||||
int desync_udp;
|
|
||||||
char split_host;
|
char split_host;
|
||||||
int def_ttl;
|
int def_ttl;
|
||||||
int mod_http;
|
int mod_http;
|
||||||
|
|
||||||
char ipv6;
|
char ipv6;
|
||||||
char resolve;
|
char resolve;
|
||||||
char udp;
|
|
||||||
int max_open;
|
int max_open;
|
||||||
int debug;
|
int debug;
|
||||||
size_t bfsize;
|
size_t bfsize;
|
||||||
@ -41,7 +37,6 @@ struct packet {
|
|||||||
};
|
};
|
||||||
extern struct packet fake_tls;
|
extern struct packet fake_tls;
|
||||||
extern struct packet fake_http;
|
extern struct packet fake_http;
|
||||||
extern struct packet fake_udp;
|
|
||||||
|
|
||||||
#define LOG_S 1
|
#define LOG_S 1
|
||||||
#define LOG_L 2
|
#define LOG_L 2
|
||||||
|
242
proxy.c
242
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)
|
void map_fix(struct sockaddr_ina *addr, char f6)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
@ -115,11 +99,11 @@ int setopts(int fd)
|
|||||||
|
|
||||||
|
|
||||||
int resolve(char *host, int len,
|
int resolve(char *host, int len,
|
||||||
struct sockaddr_ina *addr, int type)
|
struct sockaddr_ina *addr)
|
||||||
{
|
{
|
||||||
struct addrinfo hints = {0}, *res = 0;
|
struct addrinfo hints = {0}, *res = 0;
|
||||||
|
|
||||||
hints.ai_socktype = type;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_flags = AI_ADDRCONFIG;
|
hints.ai_flags = AI_ADDRCONFIG;
|
||||||
hints.ai_family = params.ipv6 ? AF_UNSPEC : AF_INET;
|
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;
|
int len = (bf + n - ie) - 2;
|
||||||
if (len < 3)
|
if (len < 3)
|
||||||
break;
|
break;
|
||||||
if (resolve(ie + 1, len, dst, SOCK_STREAM)) {
|
if (resolve(ie + 1, len, dst)) {
|
||||||
fprintf(stderr, "not resolved: %.*s\n", len, ie + 1);
|
fprintf(stderr, "not resolved: %.*s\n", len, ie + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -240,7 +224,7 @@ int handle_socks4(int fd, char *bf,
|
|||||||
|
|
||||||
|
|
||||||
int s_get_addr(char *buffer, ssize_t n,
|
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;
|
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)));
|
(r->atp == S_ATP_I6 ? S_SIZE_I6 : 0)));
|
||||||
if (n < o) {
|
if (n < o) {
|
||||||
fprintf(stderr, "ss: bad request\n");
|
fprintf(stderr, "ss: bad request\n");
|
||||||
return -S_ER_GEN;
|
return S_ER_GEN;
|
||||||
}
|
}
|
||||||
switch (r->atp) {
|
switch (r->atp) {
|
||||||
case S_ATP_I4:
|
case S_ATP_I4:
|
||||||
@ -259,58 +243,25 @@ int s_get_addr(char *buffer, ssize_t n,
|
|||||||
|
|
||||||
case S_ATP_ID:
|
case S_ATP_ID:
|
||||||
if (!params.resolve) {
|
if (!params.resolve) {
|
||||||
return -S_ER_ATP;
|
return S_ER_ATP;
|
||||||
}
|
}
|
||||||
if (r->id.len == 1 && type == SOCK_DGRAM) {
|
if (r->id.len < 3 ||
|
||||||
addr->in.sin_family = AF_INET;
|
resolve(r->id.domain, r->id.len, addr)) {
|
||||||
LOG(LOG_S, "domain len=1\n");
|
|
||||||
}
|
|
||||||
else if (resolve(r->id.domain, r->id.len, addr, type)) {
|
|
||||||
fprintf(stderr, "not resolved: %.*s\n", r->id.len, r->id.domain);
|
fprintf(stderr, "not resolved: %.*s\n", r->id.len, r->id.domain);
|
||||||
return -S_ER_HOST;
|
return S_ER_HOST;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ATP_I6:
|
case S_ATP_I6:
|
||||||
if (!params.ipv6)
|
if (!params.ipv6)
|
||||||
return -S_ER_ATP;
|
return S_ER_ATP;
|
||||||
else {
|
else {
|
||||||
addr->in6.sin6_family = AF_INET6;
|
addr->in6.sin6_family = AF_INET6;
|
||||||
addr->in6.sin6_addr = r->i6;
|
addr->in6.sin6_addr = r->i6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addr->in.sin_port = *(uint16_t *)&buffer[o - 2];
|
addr->in.sin_port = *(uint16_t *)&buffer[o - 2];
|
||||||
return o;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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,
|
static inline int on_request(struct poolhd *pool, struct eval *val,
|
||||||
char *buffer, size_t bfsize)
|
char *buffer, size_t bfsize)
|
||||||
{
|
{
|
||||||
struct sockaddr_ina dst = {0};
|
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);
|
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
||||||
if (n < 1) {
|
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;
|
struct s5_req *r = (struct s5_req *)buffer;
|
||||||
|
|
||||||
switch (r->cmd) {
|
if (r->cmd != S_CMD_CONN) {
|
||||||
case S_CMD_CONN:
|
fprintf(stderr, "ss: unsupported cmd: 0x%x\n", r->cmd);
|
||||||
offs_e = s_get_addr(buffer, n, &dst, SOCK_STREAM);
|
s5e = S_ER_CMD;
|
||||||
if (offs_e > 0) {
|
}
|
||||||
|
else {
|
||||||
|
s5e = s_get_addr(buffer, n, &dst);
|
||||||
|
if (!s5e) {
|
||||||
error = create_conn(pool, val, &dst);
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (*buffer == S_VER4) {
|
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);
|
fprintf(stderr, "ss: invalid version: 0x%x (%lu)\n", *buffer, n);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (error || offs_e < 0) {
|
if (error || s5e) {
|
||||||
if (resp_error(val->fd, errno, val->flag, -offs_e) < 0)
|
if (resp_error(val->fd, error ? errno : 0, val->flag, s5e) < 0)
|
||||||
perror("send");
|
perror("send");
|
||||||
return -1;
|
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)
|
int big_loop(int srvfd)
|
||||||
{
|
{
|
||||||
size_t bfsize = params.bfsize;
|
size_t bfsize = params.bfsize;
|
||||||
@ -776,11 +581,6 @@ int big_loop(int srvfd)
|
|||||||
del_event(pool, val);
|
del_event(pool, val);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case EV_UDP_TUNNEL:
|
|
||||||
if (on_udp_tunnel(val, buffer, bfsize))
|
|
||||||
del_event(pool, val);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case EV_IGNORE:
|
case EV_IGNORE:
|
||||||
if (etype & (POLLHUP | POLLERR | POLLRDHUP))
|
if (etype & (POLLHUP | POLLERR | POLLRDHUP))
|
||||||
del_event(pool, val);
|
del_event(pool, val);
|
||||||
|
Loading…
Reference in New Issue
Block a user