mirror of
https://github.com/hufrea/byedpi.git
synced 2024-11-25 16:25:32 +03:00
Delete transparent and HTTP proxy mode
This commit is contained in:
parent
c718bf88f0
commit
78126e5db4
4 changed files with 62 additions and 191 deletions
8
conev.h
8
conev.h
|
@ -27,11 +27,9 @@ enum eid {
|
||||||
EV_TUNNEL
|
EV_TUNNEL
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FLAG_NOSEND 1
|
#define FLAG_S4 1
|
||||||
#define FLAG_HTTP 2
|
#define FLAG_S5 2
|
||||||
#define FLAG_S4 4
|
#define FLAG_CONN 4
|
||||||
#define FLAG_S5 8
|
|
||||||
#define FLAG_CONN 16
|
|
||||||
|
|
||||||
#ifndef CONEV_H
|
#ifndef CONEV_H
|
||||||
char *eid_name[] = {
|
char *eid_name[] = {
|
||||||
|
|
18
main.c
18
main.c
|
@ -32,7 +32,6 @@ struct params params = {
|
||||||
.def_ttl = 0,
|
.def_ttl = 0,
|
||||||
.mod_http = 0,
|
.mod_http = 0,
|
||||||
|
|
||||||
.mode = MODE_PROXY_S,
|
|
||||||
.ipv6 = 1,
|
.ipv6 = 1,
|
||||||
.resolve = 1,
|
.resolve = 1,
|
||||||
.de_known = 0,
|
.de_known = 0,
|
||||||
|
@ -113,9 +112,6 @@ int main(int argc, char **argv)
|
||||||
" -D, --daemon Daemonize\n"
|
" -D, --daemon Daemonize\n"
|
||||||
" -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"
|
||||||
#ifdef __linux__
|
|
||||||
" -T, --transparent Get address with getsockopt\n"
|
|
||||||
#endif
|
|
||||||
" -N, --no-domain Deny domain resolving\n"
|
" -N, --no-domain Deny domain resolving\n"
|
||||||
" -K, --desync-known Desync only HTTP and TLS with SNI\n"
|
" -K, --desync-known Desync only HTTP and TLS with SNI\n"
|
||||||
//"Desync:\n"
|
//"Desync:\n"
|
||||||
|
@ -131,9 +127,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
const struct option options[] = {
|
const struct option options[] = {
|
||||||
{"daemon", 0, 0, 'D'},
|
{"daemon", 0, 0, 'D'},
|
||||||
{"transparent", 0, 0, 'T'},
|
|
||||||
{"http", 0, 0, 'P'}, //
|
|
||||||
{"socks", 0, 0, 'O'},
|
|
||||||
{"no-domain", 0, 0, 'N'},
|
{"no-domain", 0, 0, 'N'},
|
||||||
{"no-ipv6", 0, 0, 'X'}, //
|
{"no-ipv6", 0, 0, 'X'}, //
|
||||||
{"desync-known ", 0, 0, 'K'},
|
{"desync-known ", 0, 0, 'K'},
|
||||||
|
@ -166,7 +159,7 @@ int main(int argc, char **argv)
|
||||||
char *end = 0;
|
char *end = 0;
|
||||||
|
|
||||||
while (!invalid && (rez = getopt_long_only(argc, argv,
|
while (!invalid && (rez = getopt_long_only(argc, argv,
|
||||||
"DTPONXKHhvf:i:p:b:B:c:m:s:t:l:o:n:M:g:w:x:", options, 0)) != -1) {
|
"DNXKHhvf:i:p:b:B:c:m:s:t:l:o:n:M:g:w:x:", options, 0)) != -1) {
|
||||||
switch (rez) {
|
switch (rez) {
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
|
@ -175,21 +168,12 @@ int main(int argc, char **argv)
|
||||||
case 'f':
|
case 'f':
|
||||||
pidfile = optarg;
|
pidfile = optarg;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
|
||||||
params.mode = MODE_TRANSPARENT;
|
|
||||||
break;
|
|
||||||
case 'O':
|
|
||||||
params.mode = MODE_PROXY_S;
|
|
||||||
break;
|
|
||||||
case 'N':
|
case 'N':
|
||||||
params.resolve = 0;
|
params.resolve = 0;
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
params.ipv6 = 0;
|
params.ipv6 = 0;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
|
||||||
params.mode = MODE_PROXY_H;
|
|
||||||
break;
|
|
||||||
case 'K':
|
case 'K':
|
||||||
params.de_known = 1;
|
params.de_known = 1;
|
||||||
break;
|
break;
|
||||||
|
|
7
params.h
7
params.h
|
@ -1,11 +1,5 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
enum mode {
|
|
||||||
MODE_PROXY_H,
|
|
||||||
MODE_PROXY_S,
|
|
||||||
MODE_TRANSPARENT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum demode {
|
enum demode {
|
||||||
DESYNC_NONE,
|
DESYNC_NONE,
|
||||||
DESYNC_SPLIT,
|
DESYNC_SPLIT,
|
||||||
|
@ -22,7 +16,6 @@ struct params {
|
||||||
int def_ttl;
|
int def_ttl;
|
||||||
int mod_http;
|
int mod_http;
|
||||||
|
|
||||||
enum mode mode;
|
|
||||||
char ipv6;
|
char ipv6;
|
||||||
char resolve;
|
char resolve;
|
||||||
char de_known;
|
char de_known;
|
||||||
|
|
150
proxy.c
150
proxy.c
|
@ -22,10 +22,6 @@
|
||||||
#include <conev.h>
|
#include <conev.h>
|
||||||
#include <desync.h>
|
#include <desync.h>
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#include <linux/netfilter_ipv4.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int NOT_EXIT = 1;
|
int NOT_EXIT = 1;
|
||||||
|
|
||||||
static void on_cancel(int sig) {
|
static void on_cancel(int sig) {
|
||||||
|
@ -33,33 +29,12 @@ static void on_cancel(int sig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline int is_binded_addr(int fd, struct sockaddr_ina *dst)
|
int resolve(char *host, int len,
|
||||||
{
|
struct sockaddr_ina *addr, int type)
|
||||||
struct sockaddr_ina me;
|
|
||||||
socklen_t alen = sizeof(me);
|
|
||||||
|
|
||||||
if (getsockname(fd, &me.sa, &alen)) {
|
|
||||||
perror("getsockname");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (dst->sa.sa_family != me.sa.sa_family ||
|
|
||||||
dst->in.sin_port != me.in.sin_port) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (dst->sa.sa_family == AF_INET6 ?
|
|
||||||
!memcmp(&dst->in6.sin6_addr, &me.in6.sin6_addr, 16) :
|
|
||||||
dst->in.sin_addr.s_addr == me.in.sin_addr.s_addr) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int resolve(char *host, int len, struct sockaddr_ina *addr)
|
|
||||||
{
|
{
|
||||||
struct addrinfo hints = {0}, *res = 0;
|
struct addrinfo hints = {0}, *res = 0;
|
||||||
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = type;
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = AF_UNSPEC;
|
||||||
hints.ai_flags = AI_ADDRCONFIG;
|
hints.ai_flags = AI_ADDRCONFIG;
|
||||||
|
|
||||||
|
@ -103,13 +78,7 @@ int auth_socks5(int fd, char *buffer, ssize_t n)
|
||||||
|
|
||||||
int resp_error(int fd, int e, int flag)
|
int resp_error(int fd, int e, int flag)
|
||||||
{
|
{
|
||||||
if (flag & FLAG_HTTP) {
|
if (flag & FLAG_S4) {
|
||||||
const char *r;
|
|
||||||
if (e) r = "HTTP/1.1 504\r\n\r\n";
|
|
||||||
else r = "HTTP/1.1 200\r\n\r\n";
|
|
||||||
return send(fd, r, 16, 0);
|
|
||||||
}
|
|
||||||
else if (flag & FLAG_S4) {
|
|
||||||
struct s4_req s4r = {
|
struct s4_req s4r = {
|
||||||
.cmd = e ? S4_ER : S4_OK
|
.cmd = e ? S4_ER : S4_OK
|
||||||
};
|
};
|
||||||
|
@ -163,7 +132,7 @@ int handle_socks4(int fd, char *bf,
|
||||||
break;
|
break;
|
||||||
int len = (bf + n - ie) - 2;
|
int len = (bf + n - ie) - 2;
|
||||||
if (len > 2) {
|
if (len > 2) {
|
||||||
if (resolve(ie + 1, len, dst)) {
|
if (resolve(ie + 1, len, dst, SOCK_STREAM)) {
|
||||||
fprintf(stderr, "not resolved: %.*s\n", len, ie + 1);
|
fprintf(stderr, "not resolved: %.*s\n", len, ie + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -191,6 +160,7 @@ int handle_socks5(int fd, char *buffer,
|
||||||
size_t n, struct sockaddr_ina *addr)
|
size_t n, struct sockaddr_ina *addr)
|
||||||
{
|
{
|
||||||
if (n < sizeof(struct s5_rep)) {
|
if (n < sizeof(struct s5_rep)) {
|
||||||
|
fprintf(stderr, "ss: request to small\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
struct s5_req *r = (struct s5_req *)buffer;
|
struct s5_req *r = (struct s5_req *)buffer;
|
||||||
|
@ -202,7 +172,7 @@ int handle_socks5(int fd, char *buffer,
|
||||||
fprintf(stderr, "ss: bad request\n");
|
fprintf(stderr, "ss: bad request\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (r->cmd != S_CMD_CONN) {
|
if (r->cmd != S_CMD_CONN) {
|
||||||
fprintf(stderr, "ss: unsupported cmd: 0x%x\n", r->cmd);
|
fprintf(stderr, "ss: unsupported cmd: 0x%x\n", r->cmd);
|
||||||
er = S_ER_CMD;
|
er = S_ER_CMD;
|
||||||
}
|
}
|
||||||
|
@ -217,7 +187,7 @@ int handle_socks5(int fd, char *buffer,
|
||||||
er = S_ER_ATP;
|
er = S_ER_ATP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (resolve(r->id.domain, r->id.len, addr)) {
|
if (resolve(r->id.domain, r->id.len, addr, SOCK_STREAM)) {
|
||||||
fprintf(stderr, "not resolved: %.*s\n", r->id.len, r->id.domain);
|
fprintf(stderr, "not resolved: %.*s\n", r->id.len, r->id.domain);
|
||||||
er = S_ER_HOST;
|
er = S_ER_HOST;
|
||||||
}
|
}
|
||||||
|
@ -247,45 +217,6 @@ int handle_socks5(int fd, char *buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int handle_http(struct eval *val, char *buffer,
|
|
||||||
size_t bfsize, struct sockaddr_ina *dst)
|
|
||||||
{
|
|
||||||
char *host = 0;
|
|
||||||
uint16_t port = 443;
|
|
||||||
int cnt = 0;
|
|
||||||
|
|
||||||
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
|
||||||
if (n <= 0) {
|
|
||||||
perror("recv proxy");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int len = parse_http(buffer, n, &host, &port);
|
|
||||||
if (len <= 2) {
|
|
||||||
fprintf(stderr, "parse error\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (*host == '[') {
|
|
||||||
host++; len -= 2;
|
|
||||||
}
|
|
||||||
if (resolve(host, len, dst)) {
|
|
||||||
fprintf(stderr, "not resolved: %.*s\n", len, host);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (memcmp(buffer, "CONNECT", 7)) {
|
|
||||||
if (!(val->tmpbuf = malloc(n))) {
|
|
||||||
perror("malloc");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
val->size = n;
|
|
||||||
memcpy(val->tmpbuf, buffer, n);
|
|
||||||
} else {
|
|
||||||
val->flag |= FLAG_HTTP;
|
|
||||||
}
|
|
||||||
dst->in.sin_port = htons(port);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline int create_conn(struct poolhd *pool, struct eval *val,
|
static inline int create_conn(struct poolhd *pool, struct eval *val,
|
||||||
enum eid nxt, struct sockaddr_ina *dst)
|
enum eid nxt, struct sockaddr_ina *dst)
|
||||||
{
|
{
|
||||||
|
@ -322,7 +253,7 @@ static inline int create_conn(struct poolhd *pool, struct eval *val,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int status = connect(sfd, &dst->sa, sizeof(*dst));
|
int status = connect(sfd, &dst->sa, sizeof(*dst));
|
||||||
if (!status || errno != EINPROGRESS) {
|
if (status < 0 && errno != EINPROGRESS) {
|
||||||
perror("connect");
|
perror("connect");
|
||||||
close(sfd);
|
close(sfd);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -344,26 +275,6 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
|
||||||
{
|
{
|
||||||
struct sockaddr_ina dst = {0};
|
struct sockaddr_ina dst = {0};
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
if (params.mode == MODE_TRANSPARENT) {
|
|
||||||
socklen_t alen = sizeof(dst);
|
|
||||||
|
|
||||||
if (getsockopt(val->fd, SOL_IP, SO_ORIGINAL_DST, &dst, &alen)) {
|
|
||||||
perror("getsockopt SO_ORIGINAL_DST");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (is_binded_addr(val->fd, &dst)) {
|
|
||||||
fprintf(stderr, "drop connection to self\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mod_etype(pool, val, POLLIN, 0);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
if (params.mode == MODE_PROXY_H) {
|
|
||||||
if (handle_http(val, buffer, bfsize, &dst))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
||||||
if (n < 1) {
|
if (n < 1) {
|
||||||
if (n) perror("ss recv");
|
if (n) perror("ss recv");
|
||||||
|
@ -377,10 +288,10 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
|
||||||
val->flag = FLAG_S5;
|
val->flag = FLAG_S5;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (handle_socks5(val->fd, buffer, n, &dst)) {
|
int st = handle_socks5(val->fd, buffer, n, &dst);
|
||||||
|
if (st < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (*buffer == S_VER4) {
|
else if (*buffer == S_VER4) {
|
||||||
if (handle_socks4(val->fd, buffer, n, &dst)) {
|
if (handle_socks4(val->fd, buffer, n, &dst)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -391,8 +302,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;
|
||||||
}
|
}
|
||||||
}
|
int s = create_conn(pool, val, EV_CONNECT, &dst);
|
||||||
if (create_conn(pool, val, EV_CONNECT, &dst)) {
|
if (s) {
|
||||||
if (resp_error(val->fd, errno, val->flag) < 0)
|
if (resp_error(val->fd, errno, val->flag) < 0)
|
||||||
perror("send");
|
perror("send");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -445,24 +356,14 @@ static inline int on_accept(struct poolhd *pool, struct eval *val)
|
||||||
|
|
||||||
static inline int on_data(struct eval *val, char *buffer, size_t bfsize)
|
static inline int on_data(struct eval *val, char *buffer, size_t bfsize)
|
||||||
{
|
{
|
||||||
ssize_t n;
|
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
||||||
if (val->tmpbuf) {
|
|
||||||
buffer = val->tmpbuf;
|
|
||||||
n = val->size;
|
|
||||||
} else {
|
|
||||||
n = recv(val->fd, buffer, bfsize, 0);
|
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
if (n) perror("recv data");
|
if (n) perror("recv data");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (desync(val->pair->fd, buffer, n)) {
|
if (desync(val->pair->fd, buffer, n)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (val->tmpbuf) {
|
|
||||||
free(val->tmpbuf);
|
|
||||||
val->tmpbuf = 0;
|
|
||||||
}
|
|
||||||
val->type = EV_TUNNEL;
|
val->type = EV_TUNNEL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -472,11 +373,6 @@ static inline int on_connect(struct poolhd *pool, struct eval *val,
|
||||||
char *buffer, size_t bfsize, int e)
|
char *buffer, size_t bfsize, int e)
|
||||||
{
|
{
|
||||||
if (val->flag & FLAG_CONN) {
|
if (val->flag & FLAG_CONN) {
|
||||||
if (!e) {
|
|
||||||
val->type = EV_TUNNEL;
|
|
||||||
mod_etype(pool, val, POLLOUT, 0);
|
|
||||||
}
|
|
||||||
if (val->pair->flag) {
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
socklen_t len = sizeof(error);
|
socklen_t len = sizeof(error);
|
||||||
if (e) {
|
if (e) {
|
||||||
|
@ -491,16 +387,14 @@ static inline int on_connect(struct poolhd *pool, struct eval *val,
|
||||||
perror("send");
|
perror("send");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (e) return -1;
|
if (e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
val->type = EV_TUNNEL;
|
||||||
|
mod_etype(pool, val, POLLOUT, 0);
|
||||||
val->pair->type = EV_CONNECT;
|
val->pair->type = EV_CONNECT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (!e) {
|
|
||||||
val = val->pair;
|
|
||||||
mod_etype(pool, val, POLLIN, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (e) return -1;
|
|
||||||
return on_data(val, buffer, bfsize);
|
return on_data(val, buffer, bfsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,6 +431,8 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
||||||
if (sn < 0 && errno != EAGAIN) {
|
if (sn < 0 && errno != EAGAIN) {
|
||||||
perror("send");
|
perror("send");
|
||||||
return -1;
|
return -1;
|
||||||
|
} else if (sn < 0) {
|
||||||
|
sn = 0;
|
||||||
}
|
}
|
||||||
LOG(LOG_S, "EAGAIN, set POLLOUT (fd: %d)\n", pair->fd);
|
LOG(LOG_S, "EAGAIN, set POLLOUT (fd: %d)\n", pair->fd);
|
||||||
mod_etype(pool, val, POLLIN, 0);
|
mod_etype(pool, val, POLLIN, 0);
|
||||||
|
@ -548,12 +444,12 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
||||||
val->offset += sn;
|
val->offset += sn;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
val->size = sn > 0 ? n - sn : n;
|
val->size = n - sn;
|
||||||
if (!(val->tmpbuf = malloc(val->size))) {
|
if (!(val->tmpbuf = malloc(val->size))) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(val->tmpbuf, buffer + (sn > 0 ? sn : 0), val->size);
|
memcpy(val->tmpbuf, buffer + sn, val->size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (val->tmpbuf) {
|
else if (val->tmpbuf) {
|
||||||
|
|
Loading…
Reference in a new issue