tpws: fix-seg wait before send. tune max delay.

This commit is contained in:
bol-van 2024-11-19 09:51:32 +03:00
parent fc2d511d78
commit a93b142dcd
5 changed files with 40 additions and 22 deletions

View File

@ -812,7 +812,7 @@ tpws - это transparent proxy.
--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split. --skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split.
--local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение) --local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение)
--remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение) --remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение)
--fix-seg ; исправлять неудачи tcp сегментации ценой задержек для всех клиентов и замедления --fix-seg=<int> ; исправлять неудачи tcp сегментации ценой задержек для всех клиентов и замедления. ждать до N мс. по умолчанию 30 мс.
--split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации --split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации
--split-any-protocol ; применять сегментацию к любым пакетам. по умолчанию - только к известным протоколам (http, TLS) --split-any-protocol ; применять сегментацию к любым пакетам. по умолчанию - только к известным протоколам (http, TLS)

View File

@ -484,10 +484,11 @@ bool socket_has_notsent(int sfd)
if (getsockopt(sfd, IPPROTO_TCP, TCP_INFO, (char *)&tcpi, &ts) < 0) if (getsockopt(sfd, IPPROTO_TCP, TCP_INFO, (char *)&tcpi, &ts) < 0)
return false; return false;
if (tcpi.tcpi_state != 1) if (tcpi.tcpi_state != 1) // TCP_ESTABLISHED
return false; return false;
size_t s = (char *)&tcpi.tcpi_notsent_bytes - (char *)&tcpi.tcpi_state; size_t s = (char *)&tcpi.tcpi_notsent_bytes - (char *)&tcpi.tcpi_state;
if (ts < s) if (ts < s)
// old structure version
return false; return false;
return !!tcpi.tcpi_notsent_bytes; return !!tcpi.tcpi_notsent_bytes;
} }

View File

@ -18,6 +18,8 @@
#define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3 #define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60 #define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
#define FIX_SEG_DEFAULT_MAX_WAIT 30
enum bindll { unwanted=0, no, prefer, force }; enum bindll { unwanted=0, no, prefer, force };
#define MAX_BINDS 32 #define MAX_BINDS 32
@ -102,13 +104,13 @@ struct params_s
char connect_bind6_ifname[IF_NAMESIZE]; char connect_bind6_ifname[IF_NAMESIZE];
uint8_t proxy_type; uint8_t proxy_type;
unsigned int fix_seg;
bool no_resolve; bool no_resolve;
bool skip_nodelay; bool skip_nodelay;
bool fix_seg;
bool droproot; bool droproot;
bool daemon;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
bool daemon;
char pidfile[256]; char pidfile[256];
int maxconn,resolver_threads,maxfiles,max_orphan_time; int maxconn,resolver_threads,maxfiles,max_orphan_time;
int local_rcvbuf,local_sndbuf,remote_rcvbuf,remote_sndbuf; int local_rcvbuf,local_sndbuf,remote_rcvbuf,remote_sndbuf;

View File

@ -171,7 +171,7 @@ static void exithelp(void)
" --enable-pf\t\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n" " --enable-pf\t\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n"
#endif #endif
#if defined(__linux__) #if defined(__linux__)
" --fix-seg\t\t\t\t; fix segmentation failures at the cost of possible slowdown\n" " --fix-seg=<int>\t\t\t; fix segmentation failures at the cost of possible slowdown. wait up to N msec (default %u)\n"
#endif #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" " --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"
" --debug-level=0|1|2\t\t\t; specify debug level\n" " --debug-level=0|1|2\t\t\t; specify debug level\n"
@ -218,6 +218,9 @@ static void exithelp(void)
" --tamper-cutoff=[n]<pos>\t\t; do not tamper anymore after specified outbound stream position. default is unlimited.\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__) #if defined(__linux__) || defined(__APPLE__)
DEFAULT_TCP_USER_TIMEOUT_LOCAL,DEFAULT_TCP_USER_TIMEOUT_REMOTE, DEFAULT_TCP_USER_TIMEOUT_LOCAL,DEFAULT_TCP_USER_TIMEOUT_REMOTE,
#endif
#ifdef __linux__
FIX_SEG_DEFAULT_MAX_WAIT,
#endif #endif
HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT
); );
@ -638,7 +641,7 @@ void parse_params(int argc, char *argv[])
{ "local-tcp-user-timeout",required_argument,0,0 }, // optidx=62 { "local-tcp-user-timeout",required_argument,0,0 }, // optidx=62
{ "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=63 { "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=63
{ "mss",required_argument,0,0 }, // optidx=64 { "mss",required_argument,0,0 }, // optidx=64
{ "fix-seg",no_argument,0,0 }, // optidx=65 { "fix-seg",optional_argument,0,0 }, // optidx=65
#ifdef SPLICE_PRESENT #ifdef SPLICE_PRESENT
{ "nosplice",no_argument,0,0 }, // optidx=66 { "nosplice",no_argument,0,0 }, // optidx=66
#endif #endif
@ -1233,7 +1236,18 @@ void parse_params(int argc, char *argv[])
} }
break; break;
case 65: /* fix-seg */ case 65: /* fix-seg */
params.fix_seg = true; if (optarg)
{
i = atoi(optarg);
if (i < 0 || i > 1000)
{
DLOG_ERR("fix_seg value must be within 0..1000\n");
exit_clean(1);
}
params.fix_seg = i;
}
else
params.fix_seg = FIX_SEG_DEFAULT_MAX_WAIT;
break; break;
#ifdef SPLICE_PRESENT #ifdef SPLICE_PRESENT
case 66: /* nosplice */ case 66: /* nosplice */

View File

@ -1231,6 +1231,22 @@ static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list, uint32
bApplyDisorder = !(i & 1) && i<multisplit_count && (split_flags & SPLIT_FLAG_DISORDER); bApplyDisorder = !(i & 1) && i<multisplit_count && (split_flags & SPLIT_FLAG_DISORDER);
bApplyOOB = i==0 && (split_flags & SPLIT_FLAG_OOB); bApplyOOB = i==0 && (split_flags & SPLIT_FLAG_OOB);
len = to-from; len = to-from;
#ifdef __linux__
if (params.fix_seg)
{
unsigned int wasted;
bool bWaitOK = socket_wait_notsent(conn->partner->fd, params.fix_seg, &wasted);
if (wasted)
VPRINT("WARNING ! wasted %u ms to fix segmenation\n", wasted);
if (!bWaitOK)
DLOG_ERR("WARNING ! segmentation failed\n");
}
else
{
if (socket_has_notsent(conn->partner->fd))
DLOG_ERR("WARNING ! segmentation failed\n");
}
#endif
VPRINT("Sending multisplit part %d %zd-%zd (len %zd)%s%s : ", i+1, from, to, len, bApplyDisorder ? " with disorder" : "", bApplyOOB ? " with OOB" : ""); VPRINT("Sending multisplit part %d %zd-%zd (len %zd)%s%s : ", i+1, from, to, len, bApplyDisorder ? " with disorder" : "", bApplyOOB ? " with OOB" : "");
packet_debug(buf+from,len); packet_debug(buf+from,len);
wr = send_oob(conn->partner->fd, buf+from, len, bApplyDisorder, bApplyOOB, conn->track.dp ? conn->track.dp->oob_byte : 0); wr = send_oob(conn->partner->fd, buf+from, len, bApplyDisorder, bApplyOOB, conn->track.dp ? conn->track.dp->oob_byte : 0);
@ -1244,21 +1260,6 @@ static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list, uint32
if (wr>0) conn->partner->twr += wr; if (wr>0) conn->partner->twr += wr;
break; break;
} }
#ifdef __linux__
if (params.fix_seg)
{
unsigned int wasted;
if (!socket_wait_notsent(conn->partner->fd, 20, &wasted))
DLOG_ERR("WARNING ! segmentation failed\n");
if (wasted)
VPRINT("WARNING ! wasted %u ms to fix segmenation\n", wasted);
}
else
{
if (socket_has_notsent(conn->partner->fd))
DLOG_ERR("WARNING ! segmentation failed\n");
}
#endif
from = to; from = to;
} }
} }