tpws: tcp user timeout option

This commit is contained in:
bol-van 2024-08-27 18:31:32 +03:00
parent b5d473e121
commit 7ca2d99655
17 changed files with 94 additions and 10 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -594,6 +594,8 @@ tpws is transparent proxy.
--remote-sndbuf=<bytes> ; SO_SNDBUF for remote legs
--nosplice ; do not use splice to transfer data between sockets
--skip-nodelay ; do not set TCP_NODELAY for outgoing connections. incompatible with split.
--local-tcp-user-timeout=<seconds> ; set tcp user timeout for local leg (default : 10, 0 = system default)
--remote-tcp-user-timeout=<seconds> ; set tcp user timeout for remote leg (default : 20, 0 = system default)
--no-resolve ; disable socks5 remote dns
--resolver-threads=<int> ; number of resolver worker threads
--maxconn=<max_connections> ; max number of local legs

View File

@ -705,6 +705,8 @@ tpws - это transparent proxy.
--remote-sndbuf=<bytes> ; SO_SNDBUF для соединений proxy-target
--nosplice ; не использовать splice на linux системах
--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split.
--local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение)
--remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение)
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. единственная опция, работающая на не-http. при указании split-http-req он имеет преимущество на http.
@ -882,6 +884,14 @@ tpws поддерживает эту возможность асинхронно
Это может быть полезно для скрытия факта использования VPN. Пониженный MTU - 1 из способов обнаружения
подозрительного подключения. С tcp proxy ваши соединения неотличимы от тех, что сделал бы сам шлюз.
--local-tcp-user-timeout и --remote-tcp-user-timeout устанавливают значение таймаута в секундах
для соединений клиент-прокси и прокси-сервер. Этот таймаут соответствует опции сокета linux
TCP_USER_TIMEOUT. Под таймаутом подразумевается время, в течение которого буферизированные данные
не переданы или на переданные данные не получено подтверждение (ACK) от другой стороны.
Этот таймаут никак не касается времени отсутствия какой-либо передачи через сокет лишь потому,
что данных для передачи нет. Полезно для сокращения время закрытия подвисших соединений.
Поддерживается только на Linux и MacOS.
Способы получения списка заблокированных IP
-------------------------------------------

View File

@ -22,6 +22,9 @@ tpws в режиме socks можно запускать под более-ме
--disorder не работает из-за особенностей tcp/ip стека windows.
Может не срабатывать детект RST в autohostlist.
WSL может глючить со splice, приводя к зацикливанию процесса. Может потребоваться --nosplice.
Не поддерживается tcp user timeout.
Чтобы избавиться от исообщений об ошибке добавляйте "--local-tcp-user-timeout=0 --remote-tcp-user-timeout=0".
Эти сообщения только информативные, на работу они не влияют.
winws

View File

@ -43,6 +43,9 @@ struct params_s
bool daemon;
int maxconn,resolver_threads,maxfiles,max_orphan_time;
int local_rcvbuf,local_sndbuf,remote_rcvbuf,remote_sndbuf;
#if defined(__linux__) || defined(__APPLE__)
int tcp_user_timeout_local,tcp_user_timeout_remote;
#endif
bool tamper; // any tamper option is set
bool hostcase, hostdot, hosttab, hostnospace, methodspace, methodeol, unixeol, domcase;

View File

@ -150,6 +150,10 @@ static void exithelp(void)
" --nosplice\t\t\t\t; do not use splice to transfer data between sockets\n"
#endif
" --skip-nodelay\t\t\t\t; do not set TCP_NODELAY option for outgoing connections (incompatible with split options)\n"
#if defined(__linux__) || defined(__APPLE__)
" --local-tcp-user-timeout=<seconds>\t; set tcp user timeout for local leg (default : %d, 0 = system default)\n"
" --remote-tcp-user-timeout=<seconds>\t; set tcp user timeout for remote leg (default : %d, 0 = system default)\n"
#endif
" --maxconn=<max_connections>\n"
#ifdef SPLICE_PRESENT
" --maxfiles=<max_open_files>\t\t; should be at least (X*connections+16), where X=6 in tcp proxy mode, X=4 in tampering mode\n"
@ -161,7 +165,7 @@ static void exithelp(void)
" --pidfile=<filename>\t\t\t; write pid to file\n"
" --user=<username>\t\t\t; drop root privs\n"
" --uid=uid[:gid]\t\t\t; drop root privs\n"
#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__)
#if defined(__FreeBSD__)
" --enable-pf\t\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n"
#endif
" --debug=0|1|2|syslog|@<filename>\t; 1 and 2 means log to console and set debug level. for other targets use --debug-level.\n"
@ -203,6 +207,9 @@ static void exithelp(void)
#endif
" --tamper-start=[n]<pos>\t\t; start tampering only from specified outbound stream position. default is 0. 'n' means data block number.\n"
" --tamper-cutoff=[n]<pos>\t\t; do not tamper anymore after specified outbound stream position. default is unlimited.\n",
#if defined(__linux__) || defined(__APPLE__)
DEFAULT_TCP_USER_TIMEOUT_LOCAL,DEFAULT_TCP_USER_TIMEOUT_REMOTE,
#endif
HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT
);
exit(1);
@ -291,6 +298,10 @@ void parse_params(int argc, char *argv[])
params.binds_last = -1;
params.hostlist_auto_fail_threshold = HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT;
params.hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_DEFAULT;
#if defined(__linux__) || defined(__APPLE__)
params.tcp_user_timeout_local = DEFAULT_TCP_USER_TIMEOUT_LOCAL;
params.tcp_user_timeout_remote = DEFAULT_TCP_USER_TIMEOUT_REMOTE;
#endif
LIST_INIT(&params.hostlist_files);
LIST_INIT(&params.hostlist_exclude_files);
@ -360,13 +371,18 @@ void parse_params(int argc, char *argv[])
{ "tamper-start",required_argument,0,0 },// optidx=53
{ "tamper-cutoff",required_argument,0,0 },// optidx=54
{ "connect-bind-addr",required_argument,0,0 },// optidx=55
#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__)
#if defined(__FreeBSD__)
{ "enable-pf",no_argument,0,0 },// optidx=56
#elif defined(__APPLE__)
{ "local-tcp-user-timeout",required_argument,0,0 },// optidx=56
{ "remote-tcp-user-timeout",required_argument,0,0 },// optidx=57
#elif defined(__linux__)
{ "mss",required_argument,0,0 },// optidx=56
{ "mss-pf",required_argument,0,0 },// optidx=57
{ "local-tcp-user-timeout",required_argument,0,0 },// optidx=56
{ "remote-tcp-user-timeout",required_argument,0,0 },// optidx=57
{ "mss",required_argument,0,0 },// optidx=58
{ "mss-pf",required_argument,0,0 },// optidx=59
#ifdef SPLICE_PRESENT
{ "nosplice",no_argument,0,0 },// optidx=58
{ "nosplice",no_argument,0,0 },// optidx=60
#endif
#endif
{ "hostlist-auto-retrans-threshold",optional_argument,0,0}, // ignored. for nfqws command line compatibility
@ -851,12 +867,32 @@ void parse_params(int argc, char *argv[])
}
}
break;
#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__)
#if defined(__FreeBSD__)
case 56: /* enable-pf */
params.pf_enable = true;
break;
#elif defined(__linux__)
case 56: /* mss */
#elif defined(__linux__) || defined(__APPLE__)
case 56: /* local-tcp-user-timeout */
params.tcp_user_timeout_local = atoi(optarg);
if (params.tcp_user_timeout_local<0 || params.tcp_user_timeout_local>86400)
{
DLOG_ERR("Invalid argument for tcp user timeout. must be 0..86400\n");
exit_clean(1);
}
break;
case 57: /* remote-tcp-user-timeout */
params.tcp_user_timeout_remote = atoi(optarg);
if (params.tcp_user_timeout_remote<0 || params.tcp_user_timeout_remote>86400)
{
DLOG_ERR("Invalid argument for tcp user timeout. must be 0..86400\n");
exit_clean(1);
}
break;
#endif
#if defined(__linux__)
case 58: /* mss */
// this option does not work in any BSD and MacOS. OS may accept but it changes nothing
params.mss = atoi(optarg);
if (params.mss<88 || params.mss>32767)
@ -865,7 +901,7 @@ void parse_params(int argc, char *argv[])
exit_clean(1);
}
break;
case 57: /* mss-pf */
case 59: /* mss-pf */
if (!pf_parse(optarg,&params.mss_pf))
{
DLOG_ERR("Invalid MSS port filter.\n");
@ -873,7 +909,7 @@ void parse_params(int argc, char *argv[])
}
break;
#ifdef SPLICE_PRESENT
case 58: /* nosplice */
case 60: /* nosplice */
params.nosplice = true;
break;
#endif

View File

@ -337,6 +337,30 @@ static bool proxy_remote_conn_ack(tproxy_conn_t *conn, int sock_err)
return bres;
}
#if defined(__linux__) || defined(__APPLE__)
static void set_user_timeout(int fd, int timeout)
{
#ifdef __linux__
if (timeout>0)
{
int msec = 1000*timeout;
if (setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &msec, sizeof(int)) <0)
DLOG_PERROR("setsockopt (TCP_USER_TIMEOUT)");
}
#elif defined(__APPLE__)
if (timeout>0 && setsockopt(fd, IPPROTO_TCP, TCP_RXT_CONNDROPTIME, &timeout, sizeof(int)) <0)
DLOG_PERROR("setsockopt (TCP_RXT_CONNDROPTIME)");
#endif
}
#else
#define set_user_timeout(fd,timeout)
#endif
//Createas a socket and initiates the connection to the host specified by
//remote_addr.
//Returns -1 if something fails, >0 on success (socket fd).
@ -428,6 +452,8 @@ static int connect_remote(const struct sockaddr *remote_addr, bool bApplyConnect
}
}
set_user_timeout(remote_fd, params.tcp_user_timeout_remote);
if (connect(remote_fd, remote_addr, remote_addr->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)) < 0)
{
if(errno != EINPROGRESS)
@ -1509,6 +1535,7 @@ int event_loop(const int *listen_fd, size_t listen_fd_ct)
VPRINT("Socket fd=%d (local) connected from %s\n", conn->fd, ip_port);
}
set_user_timeout(conn->fd, params.tcp_user_timeout_local);
}
}
else
@ -1568,6 +1595,7 @@ int event_loop(const int *listen_fd, size_t listen_fd_ct)
}
else
{
DBGPRINT("conn fd=%d has no unsent\n", conn->fd);
conn->bFlowIn = false;
epoll_update_flow(conn);

View File

@ -14,6 +14,8 @@
#define SPLICE_LEN 65536
#define DEFAULT_MAX_CONN 512
#define DEFAULT_MAX_ORPHAN_TIME 5
#define DEFAULT_TCP_USER_TIMEOUT_LOCAL 10
#define DEFAULT_TCP_USER_TIMEOUT_REMOTE 20
int event_loop(const int *listen_fd, size_t listen_fd_ct);