Delete transparent and HTTP proxy mode

This commit is contained in:
ruti 2023-07-05 10:33:07 +02:00
parent c718bf88f0
commit 78126e5db4
4 changed files with 62 additions and 191 deletions

View file

@ -27,11 +27,9 @@ enum eid {
EV_TUNNEL
};
#define FLAG_NOSEND 1
#define FLAG_HTTP 2
#define FLAG_S4 4
#define FLAG_S5 8
#define FLAG_CONN 16
#define FLAG_S4 1
#define FLAG_S5 2
#define FLAG_CONN 4
#ifndef CONEV_H
char *eid_name[] = {

18
main.c
View file

@ -32,7 +32,6 @@ struct params params = {
.def_ttl = 0,
.mod_http = 0,
.mode = MODE_PROXY_S,
.ipv6 = 1,
.resolve = 1,
.de_known = 0,
@ -113,9 +112,6 @@ int main(int argc, char **argv)
" -D, --daemon Daemonize\n"
" -f, --pidfile <file> Write pid to file\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"
" -K, --desync-known Desync only HTTP and TLS with SNI\n"
//"Desync:\n"
@ -131,9 +127,6 @@ int main(int argc, char **argv)
const struct option options[] = {
{"daemon", 0, 0, 'D'},
{"transparent", 0, 0, 'T'},
{"http", 0, 0, 'P'}, //
{"socks", 0, 0, 'O'},
{"no-domain", 0, 0, 'N'},
{"no-ipv6", 0, 0, 'X'}, //
{"desync-known ", 0, 0, 'K'},
@ -166,7 +159,7 @@ int main(int argc, char **argv)
char *end = 0;
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) {
case 'D':
@ -175,21 +168,12 @@ int main(int argc, char **argv)
case 'f':
pidfile = optarg;
break;
case 'T':
params.mode = MODE_TRANSPARENT;
break;
case 'O':
params.mode = MODE_PROXY_S;
break;
case 'N':
params.resolve = 0;
break;
case 'X':
params.ipv6 = 0;
break;
case 'P':
params.mode = MODE_PROXY_H;
break;
case 'K':
params.de_known = 1;
break;

View file

@ -1,11 +1,5 @@
#include <stdio.h>
enum mode {
MODE_PROXY_H,
MODE_PROXY_S,
MODE_TRANSPARENT
};
enum demode {
DESYNC_NONE,
DESYNC_SPLIT,
@ -22,7 +16,6 @@ struct params {
int def_ttl;
int mod_http;
enum mode mode;
char ipv6;
char resolve;
char de_known;

220
proxy.c
View file

@ -22,44 +22,19 @@
#include <conev.h>
#include <desync.h>
#ifdef __linux__
#include <linux/netfilter_ipv4.h>
#endif
int NOT_EXIT = 1;
static void on_cancel(int sig) {
NOT_EXIT = 0;
}
static inline int is_binded_addr(int fd, struct sockaddr_ina *dst)
{
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)
int resolve(char *host, int len,
struct sockaddr_ina *addr, int type)
{
struct addrinfo hints = {0}, *res = 0;
hints.ai_socktype = SOCK_STREAM;
hints.ai_socktype = type;
hints.ai_family = AF_UNSPEC;
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)
{
if (flag & FLAG_HTTP) {
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) {
if (flag & FLAG_S4) {
struct s4_req s4r = {
.cmd = e ? S4_ER : S4_OK
};
@ -163,7 +132,7 @@ int handle_socks4(int fd, char *bf,
break;
int len = (bf + n - ie) - 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);
break;
}
@ -191,6 +160,7 @@ int handle_socks5(int fd, char *buffer,
size_t n, struct sockaddr_ina *addr)
{
if (n < sizeof(struct s5_rep)) {
fprintf(stderr, "ss: request to small\n");
return -1;
}
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");
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);
er = S_ER_CMD;
}
@ -217,7 +187,7 @@ int handle_socks5(int fd, char *buffer,
er = S_ER_ATP;
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);
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,
enum eid nxt, struct sockaddr_ina *dst)
{
@ -322,7 +253,7 @@ static inline int create_conn(struct poolhd *pool, struct eval *val,
return -1;
}
int status = connect(sfd, &dst->sa, sizeof(*dst));
if (!status || errno != EINPROGRESS) {
if (status < 0 && errno != EINPROGRESS) {
perror("connect");
close(sfd);
return -1;
@ -344,55 +275,35 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
{
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");
ssize_t n = recv(val->fd, buffer, bfsize, 0);
if (n < 1) {
if (n) perror("ss recv");
return -1;
}
if (*buffer == S_VER5) {
if (val->flag != FLAG_S5) {
if (auth_socks5(val->fd, buffer, n)) {
return -1;
}
val->flag = FLAG_S5;
return 0;
}
int st = handle_socks5(val->fd, buffer, n, &dst);
if (st < 0)
return -1;
}
else if (*buffer == S_VER4) {
if (handle_socks4(val->fd, buffer, n, &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;
val->flag = FLAG_S4;
}
else {
ssize_t n = recv(val->fd, buffer, bfsize, 0);
if (n < 1) {
if (n) perror("ss recv");
return -1;
}
if (*buffer == S_VER5) {
if (val->flag != FLAG_S5) {
if (auth_socks5(val->fd, buffer, n)) {
return -1;
}
val->flag = FLAG_S5;
return 0;
}
if (handle_socks5(val->fd, buffer, n, &dst)) {
return -1;
}
}
else if (*buffer == S_VER4) {
if (handle_socks4(val->fd, buffer, n, &dst)) {
return -1;
}
val->flag = FLAG_S4;
}
else {
fprintf(stderr, "ss: invalid version: 0x%x (%lu)\n", *buffer, n);
return -1;
}
fprintf(stderr, "ss: invalid version: 0x%x (%lu)\n", *buffer, n);
return -1;
}
if (create_conn(pool, val, EV_CONNECT, &dst)) {
int s = create_conn(pool, val, EV_CONNECT, &dst);
if (s) {
if (resp_error(val->fd, errno, val->flag) < 0)
perror("send");
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)
{
ssize_t n;
if (val->tmpbuf) {
buffer = val->tmpbuf;
n = val->size;
} else {
n = recv(val->fd, buffer, bfsize, 0);
if (n <= 0) {
if (n) perror("recv data");
return -1;
}
ssize_t n = recv(val->fd, buffer, bfsize, 0);
if (n <= 0) {
if (n) perror("recv data");
return -1;
}
if (desync(val->pair->fd, buffer, n)) {
return -1;
}
if (val->tmpbuf) {
free(val->tmpbuf);
val->tmpbuf = 0;
}
val->type = EV_TUNNEL;
return 0;
}
@ -472,35 +373,28 @@ static inline int on_connect(struct poolhd *pool, struct eval *val,
char *buffer, size_t bfsize, int e)
{
if (val->flag & FLAG_CONN) {
if (!e) {
val->type = EV_TUNNEL;
mod_etype(pool, val, POLLOUT, 0);
}
if (val->pair->flag) {
int error = 0;
socklen_t len = sizeof(error);
if (e) {
if (getsockopt(val->fd, SOL_SOCKET,
SO_ERROR, (char *)&error, &len)) {
perror("getsockopt SO_ERROR");
return -1;
}
}
if (resp_error(val->pair->fd,
error, val->pair->flag) < 0) {
perror("send");
int error = 0;
socklen_t len = sizeof(error);
if (e) {
if (getsockopt(val->fd, SOL_SOCKET,
SO_ERROR, (char *)&error, &len)) {
perror("getsockopt SO_ERROR");
return -1;
}
if (e) return -1;
val->pair->type = EV_CONNECT;
return 0;
}
else if (!e) {
val = val->pair;
mod_etype(pool, val, POLLIN, 1);
if (resp_error(val->pair->fd,
error, val->pair->flag) < 0) {
perror("send");
return -1;
}
if (e) {
return -1;
}
val->type = EV_TUNNEL;
mod_etype(pool, val, POLLOUT, 0);
val->pair->type = EV_CONNECT;
return 0;
}
if (e) return -1;
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) {
perror("send");
return -1;
} else if (sn < 0) {
sn = 0;
}
LOG(LOG_S, "EAGAIN, set POLLOUT (fd: %d)\n", pair->fd);
mod_etype(pool, val, POLLIN, 0);
@ -548,12 +444,12 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
val->offset += sn;
break;
}
val->size = sn > 0 ? n - sn : n;
val->size = n - sn;
if (!(val->tmpbuf = malloc(val->size))) {
perror("malloc");
return -1;
}
memcpy(val->tmpbuf, buffer + (sn > 0 ? sn : 0), val->size);
memcpy(val->tmpbuf, buffer + sn, val->size);
break;
}
else if (val->tmpbuf) {