Update MTPROXY_CHECK_TIMEOUT to 45s in docker-compose and documentation; adjust default timeout handling in code for improved performance under slow network conditions.
This commit is contained in:
@@ -58,7 +58,8 @@ func loadConfig() (*config, error) {
|
||||
}
|
||||
timeoutStr := strings.TrimSpace(os.Getenv("MTPROXY_CHECK_TIMEOUT"))
|
||||
if timeoutStr == "" {
|
||||
timeoutStr = "15s"
|
||||
// Fake-TLS + drain + req_pq/resPQ к DC часто >15s на медленных линиях и при многих прокси подряд.
|
||||
timeoutStr = "45s"
|
||||
}
|
||||
checkTimeout, err := time.ParseDuration(timeoutStr)
|
||||
if err != nil || checkTimeout <= 0 {
|
||||
|
||||
@@ -12,7 +12,7 @@ services:
|
||||
MTPROXY_LIST_FILE: /data/proxies.txt
|
||||
MTPROXY_CHECK_INTERVAL: 5m
|
||||
MTPROXY_HTTP_ADDR: ":8080"
|
||||
MTPROXY_CHECK_TIMEOUT: 15s
|
||||
MTPROXY_CHECK_TIMEOUT: 45s
|
||||
MTPROXY_DC_ID: "2"
|
||||
# Опционально: только перечисленные IP/CIDR (иначе не задавайте переменную)
|
||||
# MTPROXY_ALLOWED_IPS: "172.17.0.0/16,127.0.0.1"
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ docker run -d --name mtproxy-api --restart unless-stopped -p 8080:8080 `
|
||||
| `MTPROXY_LIST_FILE` | `/data/proxies.txt` | Путь к файлу: одна `tg://` ссылка на строку; пустые строки и строки с `#` в начале пропускаются |
|
||||
| `MTPROXY_CHECK_INTERVAL` | `5m` | Интервал между циклами (`time.ParseDuration`, например `5m`, `1h`) |
|
||||
| `MTPROXY_HTTP_ADDR` | `:8080` | Адрес прослушивания HTTP |
|
||||
| `MTPROXY_CHECK_TIMEOUT` | `15s` | Таймаут одной проверки (аналог `-timeout` CLI) |
|
||||
| `MTPROXY_CHECK_TIMEOUT` | `45s` (в демоне по умолчанию; CLI по-прежнему `15s` если не задано) | Таймаут **всей** одной проверки: TCP + Fake-TLS + MTProxy init + drain + `req_pq`/`resPQ` до DC; при медленной сети увеличьте |
|
||||
| `MTPROXY_DC_ID` | `2` | DC id (аналог `-dc-id` CLI) |
|
||||
| `MTPROXY_ALLOWED_IPS` | *(не задана)* | Если задана непустая строка — доступ к **всем** маршрутам только с перечисленных IP/CIDR; остальные получают **403** и JSON `{"error":"forbidden"}`. Формат: через запятую, пробелы допускаются: `192.168.1.10`, `10.0.0.0/8`, IPv6 и CIDR вида `2001:db8::/32`. Учитывается только **`RemoteAddr`** TCP-соединения; заголовок `X-Forwarded-For` **не** используется |
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package checkresult
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
|
||||
"mtproxy_checker/internal/checker"
|
||||
)
|
||||
@@ -18,5 +19,9 @@ func Classify(err error) (exitCode int, message string) {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
return 4, "timeout"
|
||||
}
|
||||
var ne net.Error
|
||||
if errors.As(err, &ne) && ne.Timeout() {
|
||||
return 4, "timeout"
|
||||
}
|
||||
return 1, err.Error()
|
||||
}
|
||||
|
||||
@@ -113,6 +113,9 @@ func isResPQ(mtInner []byte) bool {
|
||||
// Consumes 0x17 payloads with dec so the CTR stream stays aligned with the server; discards MTProto frames until idle.
|
||||
func DrainPostInitEE(ctx context.Context, br *bufio.Reader, conn net.Conn, dec cipher.Stream, maxWait time.Duration) error {
|
||||
end := time.Now().Add(maxWait)
|
||||
if d, ok := ctx.Deadline(); ok && d.Before(end) {
|
||||
end = d
|
||||
}
|
||||
var acc []byte
|
||||
const maxDrain = 256 << 10
|
||||
drained := 0
|
||||
@@ -122,10 +125,15 @@ func DrainPostInitEE(ctx context.Context, br *bufio.Reader, conn net.Conn, dec c
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
d := 200 * time.Millisecond
|
||||
d := 500 * time.Millisecond
|
||||
if rem := time.Until(end); rem < d {
|
||||
d = rem
|
||||
}
|
||||
if cd, ok := ctx.Deadline(); ok {
|
||||
if rem := time.Until(cd); rem < d {
|
||||
d = rem
|
||||
}
|
||||
}
|
||||
if d <= 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -185,22 +193,27 @@ func VerifyResPQ(ctx context.Context, conn net.Conn, enc, dec cipher.Stream, tls
|
||||
|
||||
deadline, ok := ctx.Deadline()
|
||||
if !ok {
|
||||
deadline = time.Now().Add(15 * time.Second)
|
||||
deadline = time.Now().Add(60 * time.Second)
|
||||
}
|
||||
|
||||
var acc []byte
|
||||
|
||||
const maxAcc = 256 << 10
|
||||
// Один read ждёт ответ DC; 3s мало при нагрузке/гео — держим до 30s, но не дольше ctx.
|
||||
const perReadSlack = 30 * time.Second
|
||||
for time.Now().Before(deadline) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
chunkDeadline := time.Now().Add(3 * time.Second)
|
||||
chunkDeadline := time.Now().Add(perReadSlack)
|
||||
if chunkDeadline.After(deadline) {
|
||||
chunkDeadline = deadline
|
||||
}
|
||||
if !chunkDeadline.After(time.Now().Add(50 * time.Millisecond)) {
|
||||
return fmt.Errorf("%w: not enough time left waiting for resPQ", context.DeadlineExceeded)
|
||||
}
|
||||
_ = conn.SetReadDeadline(chunkDeadline)
|
||||
var chunk []byte
|
||||
var rerr error
|
||||
|
||||
Reference in New Issue
Block a user