diff --git a/binaries/aarch64/tpws b/binaries/aarch64/tpws index b3149de..b18287a 100755 Binary files a/binaries/aarch64/tpws and b/binaries/aarch64/tpws differ diff --git a/binaries/arm/tpws b/binaries/arm/tpws index 277b38f..2bd0960 100755 Binary files a/binaries/arm/tpws and b/binaries/arm/tpws differ diff --git a/binaries/mac64/tpws b/binaries/mac64/tpws index 98125df..ee436be 100755 Binary files a/binaries/mac64/tpws and b/binaries/mac64/tpws differ diff --git a/binaries/mips32r1-lsb/tpws b/binaries/mips32r1-lsb/tpws index d96e5d9..590d4e8 100755 Binary files a/binaries/mips32r1-lsb/tpws and b/binaries/mips32r1-lsb/tpws differ diff --git a/binaries/mips32r1-msb/tpws b/binaries/mips32r1-msb/tpws index 7045e6c..2c97b5a 100755 Binary files a/binaries/mips32r1-msb/tpws and b/binaries/mips32r1-msb/tpws differ diff --git a/binaries/mips64r2-msb/tpws b/binaries/mips64r2-msb/tpws index f903fbb..720373d 100755 Binary files a/binaries/mips64r2-msb/tpws and b/binaries/mips64r2-msb/tpws differ diff --git a/binaries/ppc/tpws b/binaries/ppc/tpws index 7624a42..99ef3de 100755 Binary files a/binaries/ppc/tpws and b/binaries/ppc/tpws differ diff --git a/binaries/x86/tpws b/binaries/x86/tpws index d9fe7e7..0571317 100755 Binary files a/binaries/x86/tpws and b/binaries/x86/tpws differ diff --git a/binaries/x86_64/tpws b/binaries/x86_64/tpws index 405eb47..e3d781e 100755 Binary files a/binaries/x86_64/tpws and b/binaries/x86_64/tpws differ diff --git a/binaries/x86_64/tpws_wsl.tgz b/binaries/x86_64/tpws_wsl.tgz index 1140d3f..ba5b991 100644 Binary files a/binaries/x86_64/tpws_wsl.tgz and b/binaries/x86_64/tpws_wsl.tgz differ diff --git a/docs/readme.eng.md b/docs/readme.eng.md index 1a23886..d754a14 100644 --- a/docs/readme.eng.md +++ b/docs/readme.eng.md @@ -594,6 +594,8 @@ tpws is transparent proxy. --remote-sndbuf= ; 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= ; set tcp user timeout for local leg (default : 10, 0 = system default) + --remote-tcp-user-timeout= ; set tcp user timeout for remote leg (default : 20, 0 = system default) --no-resolve ; disable socks5 remote dns --resolver-threads= ; number of resolver worker threads --maxconn= ; max number of local legs diff --git a/docs/readme.txt b/docs/readme.txt index 0d1c40a..a8fdc29 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -705,6 +705,8 @@ tpws - это transparent proxy. --remote-sndbuf= ; SO_SNDBUF для соединений proxy-target --nosplice ; не использовать splice на linux системах --skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split. + --local-tcp-user-timeout= ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение) + --remote-tcp-user-timeout= ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение) --split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host --split-pos= ; делить все посылы на сегменты в указанной позиции. единственная опция, работающая на не-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 ------------------------------------------- diff --git a/docs/windows.txt b/docs/windows.txt index a56ee80..b71d7ff 100644 --- a/docs/windows.txt +++ b/docs/windows.txt @@ -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 diff --git a/tpws/params.h b/tpws/params.h index 95105d9..ba65e82 100644 --- a/tpws/params.h +++ b/tpws/params.h @@ -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; diff --git a/tpws/tpws.c b/tpws/tpws.c index ff4a97f..9e017c5 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -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=\t; set tcp user timeout for local leg (default : %d, 0 = system default)\n" + " --remote-tcp-user-timeout=\t; set tcp user timeout for remote leg (default : %d, 0 = system default)\n" +#endif " --maxconn=\n" #ifdef SPLICE_PRESENT " --maxfiles=\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=\t\t\t; write pid to file\n" " --user=\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|@\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]\t\t; start tampering only from specified outbound stream position. default is 0. 'n' means data block number.\n" " --tamper-cutoff=[n]\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(¶ms.hostlist_files); LIST_INIT(¶ms.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,¶ms.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 diff --git a/tpws/tpws_conn.c b/tpws/tpws_conn.c index c14dcdf..d92e1b1 100644 --- a/tpws/tpws_conn.c +++ b/tpws/tpws_conn.c @@ -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); diff --git a/tpws/tpws_conn.h b/tpws/tpws_conn.h index 248ddcd..31abbd2 100644 --- a/tpws/tpws_conn.h +++ b/tpws/tpws_conn.h @@ -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);