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 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
View file

@ -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;

View file

@ -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
View file

@ -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) {