From ff3398c6a93cdf1f598d4633d66aef072d904a96 Mon Sep 17 00:00:00 2001
From: Vladimir Dubrovin <3proxy@3proxy.ru>
Date: Thu, 20 Aug 2026 18:32:25 +0300
Subject: [PATCH] Commit as 0.9.9
---
CHANGELOG | 44 ++++++--------
CHANGELOG.rus | 44 ++++++--------
RELEASE | 2 +-
debian/changelog | 6 ++
doc/changelog/0/9/9 | 16 +++++
doc/html/man5/3proxy.cfg.5.html | 102 +++++++++++++++++++++++++++++---
scripts/rh/3proxy.spec | 2 +-
src/version.h | 6 +-
8 files changed, 155 insertions(+), 67 deletions(-)
create mode 100644 doc/changelog/0/9/9
diff --git a/CHANGELOG b/CHANGELOG
index 1c976e2..7493453 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,28 +1,18 @@
-3proxy-0.9.8 Released August, 7 2026
+3proxy-0.9.9 Released August, 20 2026
-!! Fix: use-after-free on the ftp:// request path in HTTP proxy, a request buffer reallocation left a stale pointer; heap corruption, requires authenticated access
-!! Fix: buffer overflow in radsend() with an oversized request hostname; RADIUS is experimental, log radius or auth radius with fakeresolve is required to reach it
-!! Fix: buffer overflow in smtpp when relaying AUTH LOGIN credentials to a server which offers AUTH PLAIN only; requires authorised access to smtpp
-!! Fix: out-of-bounds read in tlspr on a malformed TLS ClientHello
-!! Fix: LDAP injection and unsafe counter file names in LdapPlugin; the plugin is unsupported and is not built with 3proxy
-!! Fix: password and hash comparison in strong authentication is constant-time now
-!! Fix: bounds validation and match/depth limits in pcre filters
-+ imapp: IMAPv4 proxy added, supports LOGIN command, AUTH PLAIN and AUTH LOGIN
-+ STARTTLS support for smtpp, pop3p, imapp and tlspr, on both client and server side; -x option to disable
-+ wolfSSL is supported as an alternative TLS backend, WOLFSSL_CHECK=true selects it (wolfSSL must be built with --enable-opensslextra)
-+ Chunked Transfer-Encoding from client is supported by HTTP proxy
-+ dnspr: -F option added, fake resolve to redirect traffic
-+ ucrt64 build support; static libraries support in Makefile.win
-+ minimal and busybox Docker images switched to musl + wolfSSL
-- splice() support is not built by default anymore, it is slower than the read/write path for most traffic; add -DWITHSPLICE to build it
-! Fix: hashtable item was added with wrong index on table grow; with large username/password tables it could cause a single record to be missing
-! Fix: race conditions; stack overflow on FreeBSD
-! Fix: generated certificates are X.509 v3 with basicConstraints CA:FALSE and extendedKeyUsage serverAuth, required by Apple TLS stack and by Chrome on macOS/iOS
-! Fix: dnspr was broken since udppm rewrite
-! Fix: short cleartext passwords failed authentication
-! Fix: parent negotiation after sending PROXY protocol header
-! Fix: maxchild dropped to 100 on config reload if not set explicitly
-! Fix: getrandom() is not used with glibc below 2.25
-! Fix: IPV6_BOUND_IF definition for legacy MacOS
-! Fix: cmake build, arm64 Docker build, Makefile.win with UCRT
-! Multiple minor bugfixes and code cleanup
+! Fix: DNS replies are validated now: a reply from an address other than the nameserver the query was sent to, and a reply with a question section not matching the query, are dropped; both were accepted before
+! Fix: socket leak with SOCKSv5 UDP ASSOCIATE through a parent proxy, sockets were accumulated in CLOSE_WAIT state until descriptors ran out
+! Fix: file descriptor leak in HTTP proxy on the ftp:// request path
+! Fix: crash with illegal instruction on some platforms (e.g. some musl based Linux builds), caused by a memcpy on overlapping buffers
+! Fix: extip and ha (HAProxy PROXY protocol) parents are applied to SOCKSv5 UDP ASSOCIATE now
+! Fix: only socks5 and socks5+ parents are tried for UDP ASSOCIATE, other parent types can not be used for UDP
+! Fix: udppm through a SOCKSv5 parent did not work
+! Fix: -Ne and -Ni options were never applied, the option letter was not parsed; -Ne is not applied to the UDP ASSOCIATE reply anymore, -Ni is applied to it
+! Fix: -4 / -6 handling for UDP in socks; a single UDP association can use both IPv4 and IPv6 destinations now
+! Fix: a datagram with a null destination address is dropped now
+! Fix: DNS over TCP: a reply which did not fit a single read was never processed
+! Documentation: "How to apply ACLs to UDP traffic" added to HOWTO; authentication cache, ACL and UDP notes added to "Optimizing 3proxy for High Load" and to security recommendations
++ SOCKSv5 UDP: the destination of every datagram is authorized, so ACLs limiting the destination address, host name or port apply to UDP traffic now; the parent proxy and the external address are selected for the destination of the datagram and not for the UDP ASSOCIATE request
++ socks: -U option to control what happens when the destination changes within an UDP association: log it, authorize it, both (default) or neither
++ -C option (for TCP services) to terminate the session as soon as any of the sides closes the connection; by default the session is kept until both sides close it (TCP half-close)
++ timeouts: LINGER value added (11th, default 5), used to deliver buffered data after one of the sides has closed its sending side and as SO_LINGER value on outgoing connections
diff --git a/CHANGELOG.rus b/CHANGELOG.rus
index 64df875..a1e3587 100644
--- a/CHANGELOG.rus
+++ b/CHANGELOG.rus
@@ -1,28 +1,18 @@
-3proxy-0.9.8 Вышел 7 Августа 2026
+3proxy-0.9.9 Вышел 20 Августа 2026
-!! Исправление: use-after-free на пути обработки запроса ftp:// в HTTP-прокси, перевыделение буфера запроса оставляло устаревший указатель; повреждение кучи, требуется аутентифицированный доступ
-!! Исправление: переполнение буфера в radsend() при слишком длинном имени хоста в запросе; RADIUS является экспериментальным, для достижения кода необходимы log radius или auth radius в сочетании с fakeresolve
-!! Исправление: переполнение буфера в smtpp при передаче учётных данных AUTH LOGIN серверу, поддерживающему только AUTH PLAIN; требуется авторизованный доступ к smtpp
-!! Исправление: чтение за границами буфера в tlspr при некорректном TLS ClientHello
-!! Исправление: LDAP-инъекция и небезопасные имена файлов счётчиков в LdapPlugin; плагин не поддерживается и не собирается вместе с 3proxy
-!! Исправление: сравнение паролей и хешей в strong-аутентификации теперь выполняется за постоянное время
-!! Исправление: проверка границ и ограничения match/depth в pcre-фильтрах
-+ imapp: добавлен IMAPv4-прокси, поддерживаются команда LOGIN, AUTH PLAIN и AUTH LOGIN
-+ Поддержка STARTTLS для smtpp, pop3p, imapp и tlspr, как со стороны клиента, так и со стороны сервера; опция -x для отключения
-+ wolfSSL поддерживается как альтернативный TLS-бэкенд, выбирается через WOLFSSL_CHECK=true (wolfSSL должен быть собран с --enable-opensslextra)
-+ HTTP-прокси поддерживает Transfer-Encoding: chunked от клиента
-+ dnspr: добавлена опция -F, фиктивное разрешение имён для перенаправления трафика
-+ Поддержка сборки ucrt64; поддержка статических библиотек в Makefile.win
-+ Docker-образы minimal и busybox переведены на musl + wolfSSL
-- Поддержка splice() больше не собирается по умолчанию, она медленнее пути read/write для большинства видов трафика; для сборки добавьте -DWITHSPLICE
-! Исправление: элемент хеш-таблицы добавлялся с неверным индексом при росте таблицы; на больших таблицах пользователей/паролей это могло приводить к отсутствию одной записи
-! Исправление: состояния гонки; переполнение стека во FreeBSD
-! Исправление: генерируемые сертификаты имеют формат X.509 v3 с basicConstraints CA:FALSE и extendedKeyUsage serverAuth, что требуется TLS-стеком Apple и Chrome в macOS/iOS
-! Исправление: dnspr был сломан со времён переписывания udppm
-! Исправление: короткие пароли в открытом виде не проходили аутентификацию
-! Исправление: согласование с родителем после отправки заголовка PROXY protocol
-! Исправление: maxchild сбрасывался в 100 при перезагрузке конфигурации, если не задан явно
-! Исправление: getrandom() не используется с glibc ниже 2.25
-! Исправление: определение IPV6_BOUND_IF для устаревших версий MacOS
-! Исправление: сборка cmake, сборка Docker для arm64, Makefile.win с UCRT
-! Множество мелких исправлений и очистка кода
+! Исправление: ответы DNS теперь проверяются: ответ с адреса, отличного от адреса сервера имён, которому был отправлен запрос, а также ответ с секцией вопроса, не совпадающей с запросом, отбрасываются; ранее оба принимались
+! Исправление: утечка сокетов при SOCKSv5 UDP ASSOCIATE через вышестоящий прокси, сокеты накапливались в состоянии CLOSE_WAIT до исчерпания дескрипторов
+! Исправление: утечка файловых дескрипторов в HTTP-прокси на пути обработки запроса ftp://
+! Исправление: аварийное завершение с недопустимой инструкцией на некоторых платформах (например, в некоторых сборках Linux на основе musl) из-за memcpy на перекрывающихся буферах
+! Исправление: родители типа extip и ha (HAProxy PROXY protocol) теперь применяются к SOCKSv5 UDP ASSOCIATE
+! Исправление: для UDP ASSOCIATE используются только родители socks5 и socks5+, остальные типы для UDP неприменимы
+! Исправление: udppm через вышестоящий прокси SOCKSv5 не работал
+! Исправление: опции -Ne и -Ni никогда не применялись, буква опции не разбиралась; -Ne больше не применяется к ответу на UDP ASSOCIATE, -Ni применяется к нему
+! Исправление: обработка -4 / -6 для UDP в socks; одна UDP-ассоциация теперь может использовать адреса назначения и IPv4, и IPv6
+! Исправление: датаграмма с нулевым адресом назначения теперь отбрасывается
+! Исправление: DNS поверх TCP: ответ, не помещавшийся в одно чтение, никогда не обрабатывался
+! Документация: в HOWTO добавлен раздел "Как применять ACL к UDP-трафику"; в "Optimizing 3proxy for High Load" и в рекомендации по безопасности добавлены заметки о кэше аутентификации, ACL и UDP
++ SOCKSv5 UDP: адрес назначения каждой датаграммы авторизуется, поэтому ACL, ограничивающие адрес назначения, имя хоста или порт, теперь применяются к UDP-трафику; вышестоящий прокси и внешний адрес выбираются для адреса назначения датаграммы, а не для запроса UDP ASSOCIATE
++ socks: опция -U для управления тем, что происходит при смене адреса назначения в рамках UDP-ассоциации: журналировать, авторизовать, и то и другое (по умолчанию) или ничего
++ Опция -C (для TCP-сервисов) завершает сессию, как только любая из сторон закрывает соединение; по умолчанию сессия сохраняется, пока соединение не закроют обе стороны (полузакрытие TCP)
++ timeouts: добавлено значение LINGER (11-е, по умолчанию 5), используется для доставки буферизованных данных после того, как одна из сторон закрыла свою передающую сторону, а также как значение SO_LINGER для исходящих соединений
diff --git a/RELEASE b/RELEASE
index b5d0ec5..6f060dc 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-0.9.8
\ No newline at end of file
+0.9.9
\ No newline at end of file
diff --git a/debian/changelog b/debian/changelog
index 9ef7cf9..0e909bc 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+3proxy (0.9.9-1) buster; urgency=medium
+
+ *3proxy 0.9.9 initial build
+
+ -- z3APA3A <3apa3a@3proxy.org> Thu, 20 Aug 2026 18:29:37 +0300
+
3proxy (0.9.8-1) buster; urgency=medium
*3proxy 0.9.8 initial build
diff --git a/doc/changelog/0/9/9 b/doc/changelog/0/9/9
new file mode 100644
index 0000000..65b5ca4
--- /dev/null
+++ b/doc/changelog/0/9/9
@@ -0,0 +1,16 @@
+! Fix: DNS replies are validated now: a reply from an address other than the nameserver the query was sent to, and a reply with a question section not matching the query, are dropped; both were accepted before
+! Fix: socket leak with SOCKSv5 UDP ASSOCIATE through a parent proxy, sockets were accumulated in CLOSE_WAIT state until descriptors ran out
+! Fix: file descriptor leak in HTTP proxy on the ftp:// request path
+! Fix: crash with illegal instruction on some platforms (e.g. some musl based Linux builds), caused by a memcpy on overlapping buffers
+! Fix: extip and ha (HAProxy PROXY protocol) parents are applied to SOCKSv5 UDP ASSOCIATE now
+! Fix: only socks5 and socks5+ parents are tried for UDP ASSOCIATE, other parent types can not be used for UDP
+! Fix: udppm through a SOCKSv5 parent did not work
+! Fix: -Ne and -Ni options were never applied, the option letter was not parsed; -Ne is not applied to the UDP ASSOCIATE reply anymore, -Ni is applied to it
+! Fix: -4 / -6 handling for UDP in socks; a single UDP association can use both IPv4 and IPv6 destinations now
+! Fix: a datagram with a null destination address is dropped now
+! Fix: DNS over TCP: a reply which did not fit a single read was never processed
+! Documentation: "How to apply ACLs to UDP traffic" added to HOWTO; authentication cache, ACL and UDP notes added to "Optimizing 3proxy for High Load" and to security recommendations
++ SOCKSv5 UDP: the destination of every datagram is authorized, so ACLs limiting the destination address, host name or port apply to UDP traffic now; the parent proxy and the external address are selected for the destination of the datagram and not for the UDP ASSOCIATE request
++ socks: -U option to control what happens when the destination changes within an UDP association: log it, authorize it, both (default) or neither
++ -C option (for TCP services) to terminate the session as soon as any of the sides closes the connection; by default the session is kept until both sides close it (TCP half-close)
++ timeouts: LINGER value added (11th, default 5), used to deliver buffered data after one of the sides has closed its sending side and as SO_LINGER value on outgoing connections
diff --git a/doc/html/man5/3proxy.cfg.5.html b/doc/html/man5/3proxy.cfg.5.html
index b91fdb2..1981738 100644
--- a/doc/html/man5/3proxy.cfg.5.html
+++ b/doc/html/man5/3proxy.cfg.5.html
@@ -221,7 +221,30 @@ built by default and is disabled even when built, because
current Linux does not implement SPLICE_F_MOVE, so no real
zero-copy takes place and the read/write path is faster for
most traffic. Rebuild with -DWITHSPLICE to make -s
-available, -s0 disables it explicitly.
+available, -s0 disables it explicitly.
+-C
+(for TCP services) a connection closed by any of the sides
+terminates the session, buffered data is delivered before
+the sockets are closed. By default the session is kept until
+both sides close the connection (TCP half-close). Half-close
+is required for the protocols where one of the sides closes
+its sending side and expects the answer, but it keeps the
+socket of the side which has already closed the connection
+in CLOSE_WAIT state. Use -C to close both sockets as soon as
+any of the sides closes the connection, -C1 to request the
+default behaviour explicitly.
+-U[MODE]
+(for socks) what to do when the destination changes within
+an UDP association: 1 - log it, 2 - authorize
+it, 3 - both, the default, 0 (same as bare
+-U) - neither. The destination of the first datagram
+is always authorized and logged. With -U0 and
+-U1 the destination is not authorized again, so ACLs
+limiting the destination only apply to the first destination
+of the association, and the parent proxy and the external
+address selected for it are kept for the whole association.
+Use -U2 to keep the authorization and to drop the
+per-destination log records only.
(for dnspr) simple, do not use resolver and 3proxy cache,
always use external DNS server.
(for udppm) singlepacket, expect only one packet from both
@@ -400,9 +423,9 @@ and %F as filename.
maxseg
<value>
@@ -584,7 +612,15 @@ but the ACL authorization result is also cached and not
re-evaluated on each request. Faster than cache, but
ACL changes do not take effect for cached users until the
cache entry expires. Use cache if ACLs may change
-during the cache lifetime.
+during the cache lifetime. Because the ACL is not walked on
+a cache hit, no redirection is applied to a request served
+from the cache: it is sent directly instead of through the
+parent proxy of the matching ACL entry, with no error
+reported. Do not use cacheacl together with parent
+proxies, use cache instead. The only redirection type
+which survives is extip, and only if ext is a
+part of the authcache key, because the external
+address is then restored from the cache entry.
radius - authentication with RADIUS.
Plugins may add additional authentication types.
parent <weight> <type> <ip> <port> diff --git a/scripts/rh/3proxy.spec b/scripts/rh/3proxy.spec index b55ef11..108cdc8 100644 --- a/scripts/rh/3proxy.spec +++ b/scripts/rh/3proxy.spec @@ -1,5 +1,5 @@ Name: 3proxy -Version: 0.9.8 +Version: 0.9.9 Release: 1%{?dist} Summary: 3proxy tiny proxy server License: GPL/LGPL/Apache/BSD diff --git a/src/version.h b/src/version.h index e3d5f0a..33ad5cf 100644 --- a/src/version.h +++ b/src/version.h @@ -1,14 +1,14 @@ #ifndef VERSION -#define VERSION "3proxy-0.9.8" +#define VERSION "3proxy-0.9.9" #endif #ifndef BUILDDATE #define BUILDDATE "" #endif #define MAJOR3PROXY 0 #define SUBMAJOR3PROXY 9 -#define MINOR3PROXY 8 +#define MINOR3PROXY 9 #define SUBMINOR3PROXY 0 -#define RELEASE3PROXY "3proxy-0.9.8(" BUILDDATE ")\0" +#define RELEASE3PROXY "3proxy-0.9.9(" BUILDDATE ")\0" #ifndef YEAR3PROXY #define YEAR3PROXY "2026" #endif