mirror of
https://github.com/hufrea/byedpi.git
synced 2024-12-22 14:25:44 +00:00
Transparent proxy mode (#114)
* Transparent proxy * Typo errors * long long -> intmax_t for printing time_t --------- Co-authored-by: vel21ripn <> Co-authored-by: Konstantin Saliy <ksaliy@s-terra.ru>
This commit is contained in:
parent
1d6c0a132e
commit
02a9e046fd
2
extend.c
2
extend.c
@ -85,7 +85,7 @@ int mode_add_get(struct sockaddr_ina *dst, int m)
|
|||||||
}
|
}
|
||||||
time(&t);
|
time(&t);
|
||||||
if (t > val->time + params.cache_ttl) {
|
if (t > val->time + params.cache_ttl) {
|
||||||
LOG(LOG_S, "time=%ld, now=%ld, ignore\n", val->time, t);
|
LOG(LOG_S, "time=%jd, now=%jd, ignore\n", (intmax_t)val->time, (intmax_t)t);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return val->m;
|
return val->m;
|
||||||
|
12
main.c
12
main.c
@ -61,6 +61,9 @@ struct params params = {
|
|||||||
const char help_text[] = {
|
const char help_text[] = {
|
||||||
" -i, --ip, <ip> Listening IP, default 0.0.0.0\n"
|
" -i, --ip, <ip> Listening IP, default 0.0.0.0\n"
|
||||||
" -p, --port <num> Listening port, default 1080\n"
|
" -p, --port <num> Listening port, default 1080\n"
|
||||||
|
#ifdef __linux__
|
||||||
|
" -E, --transparent Transparent proxy mode\n"
|
||||||
|
#endif
|
||||||
" -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 association\n"
|
" -U, --no-udp Deny UDP association\n"
|
||||||
@ -116,6 +119,9 @@ const struct option options[] = {
|
|||||||
{"version", 0, 0, 'v'},
|
{"version", 0, 0, 'v'},
|
||||||
{"ip", 1, 0, 'i'},
|
{"ip", 1, 0, 'i'},
|
||||||
{"port", 1, 0, 'p'},
|
{"port", 1, 0, 'p'},
|
||||||
|
#ifdef __linux__
|
||||||
|
{"transparent", 0, 0, 'E'},
|
||||||
|
#endif
|
||||||
{"conn-ip", 1, 0, 'I'},
|
{"conn-ip", 1, 0, 'I'},
|
||||||
{"buf-size", 1, 0, 'b'},
|
{"buf-size", 1, 0, 'b'},
|
||||||
{"max-conn", 1, 0, 'c'},
|
{"max-conn", 1, 0, 'c'},
|
||||||
@ -492,6 +498,11 @@ int main(int argc, char **argv)
|
|||||||
case 'U':
|
case 'U':
|
||||||
params.udp = 0;
|
params.udp = 0;
|
||||||
break;
|
break;
|
||||||
|
#ifdef __linux__
|
||||||
|
case 'E':
|
||||||
|
params.transparent = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
printf(help_text);
|
printf(help_text);
|
||||||
@ -868,6 +879,7 @@ int main(int argc, char **argv)
|
|||||||
clear_params();
|
clear_params();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = run((struct sockaddr_ina *)¶ms.laddr);
|
int status = run((struct sockaddr_ina *)¶ms.laddr);
|
||||||
clear_params();
|
clear_params();
|
||||||
return status;
|
return status;
|
||||||
|
1
params.h
1
params.h
@ -105,6 +105,7 @@ struct params {
|
|||||||
size_t bfsize;
|
size_t bfsize;
|
||||||
struct sockaddr_in6 baddr;
|
struct sockaddr_in6 baddr;
|
||||||
struct sockaddr_in6 laddr;
|
struct sockaddr_in6 laddr;
|
||||||
|
char transparent;
|
||||||
struct mphdr *mempool;
|
struct mphdr *mempool;
|
||||||
|
|
||||||
char *protect_path;
|
char *protect_path;
|
||||||
|
54
proxy.c
54
proxy.c
@ -32,6 +32,10 @@
|
|||||||
#if defined(__linux__) && defined(__GLIBC__)
|
#if defined(__linux__) && defined(__GLIBC__)
|
||||||
extern int accept4(int, struct sockaddr *__restrict, socklen_t *__restrict, int);
|
extern int accept4(int, struct sockaddr *__restrict, socklen_t *__restrict, int);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __linux__
|
||||||
|
/* For SO_ORIGINAL_DST only (which is 0x50) */
|
||||||
|
#include "linux/netfilter_ipv4.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -197,6 +201,17 @@ int resp_error(int fd, int e, int flag)
|
|||||||
}
|
}
|
||||||
return resp_s5_error(fd, e);
|
return resp_s5_error(fd, e);
|
||||||
}
|
}
|
||||||
|
#ifdef __linux__
|
||||||
|
if (params.transparent &&
|
||||||
|
(e == ECONNREFUSED || e == ETIMEDOUT)) {
|
||||||
|
struct linger l = { .l_onoff = 1 };
|
||||||
|
if (setsockopt(fd,
|
||||||
|
SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) {
|
||||||
|
uniperror("setsockopt SO_LINGER");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +257,7 @@ int s5_get_addr(char *buffer, size_t n,
|
|||||||
struct sockaddr_ina *addr, int type)
|
struct sockaddr_ina *addr, int type)
|
||||||
{
|
{
|
||||||
if (n < S_SIZE_MIN) {
|
if (n < S_SIZE_MIN) {
|
||||||
LOG(LOG_E, "ss: request to small\n");
|
LOG(LOG_E, "ss: request too small\n");
|
||||||
return -S_ER_GEN;
|
return -S_ER_GEN;
|
||||||
}
|
}
|
||||||
struct s5_req *r = (struct s5_req *)buffer;
|
struct s5_req *r = (struct s5_req *)buffer;
|
||||||
@ -519,6 +534,34 @@ int udp_associate(struct poolhd *pool,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
static inline int transp_conn(struct poolhd *pool, struct eval *val)
|
||||||
|
{
|
||||||
|
struct sockaddr_ina remote, self;
|
||||||
|
socklen_t rlen = sizeof(remote), slen = sizeof(self);
|
||||||
|
if (getsockopt(val->fd,
|
||||||
|
IPPROTO_IP, SO_ORIGINAL_DST, &remote, &rlen) != 0) {
|
||||||
|
uniperror("getsockopt SO_ORIGINAL_DST");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (getsockname(val->fd, &self.sa, &slen) < 0) {
|
||||||
|
uniperror("getsockname");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (self.sa.sa_family == remote.sa.sa_family &&
|
||||||
|
self.in.sin_port == remote.in.sin_port &&
|
||||||
|
addr_equ(&self, &remote)) {
|
||||||
|
LOG(LOG_E, "connect to self, ignore\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int error = connect_hook(pool, val, &remote, EV_CONNECT);
|
||||||
|
if (error) {
|
||||||
|
uniperror("connect_hook");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline int on_accept(struct poolhd *pool, struct eval *val)
|
static inline int on_accept(struct poolhd *pool, struct eval *val)
|
||||||
{
|
{
|
||||||
@ -565,6 +608,12 @@ static inline int on_accept(struct poolhd *pool, struct eval *val)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
rval->in6 = client.in6;
|
rval->in6 = client.in6;
|
||||||
|
#ifdef __linux__
|
||||||
|
if (params.transparent && transp_conn(pool, rval) < 0) {
|
||||||
|
close(c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -753,7 +802,7 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (n < S_SIZE_MIN) {
|
if (n < S_SIZE_MIN) {
|
||||||
LOG(LOG_E, "ss: request to small (%zd)\n", n);
|
LOG(LOG_E, "ss: request too small (%zd)\n", n);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
struct s5_req *r = (struct s5_req *)buffer;
|
struct s5_req *r = (struct s5_req *)buffer;
|
||||||
@ -982,4 +1031,3 @@ int run(struct sockaddr_ina *srv)
|
|||||||
}
|
}
|
||||||
return event_loop(fd);
|
return event_loop(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user