В Net::SMTP 3.16 нет конструктора с предварительно подключённым SOCKS
Net::SMTP 3.16 не документирует параметр конструктора для заранее подключённого сокета. Сохраняйте приветствие SMTP, EHLO и порядок TLS при выборе интеграции транспорта через прокси.
Net::SMTP 3.16 не документирует параметр конструктора для SOCKS или заранее подключённого сокета. Обёртывание файлового дескриптора унаследованным new_from_fd не запускает его конструктор SMTP. Успешное соединение SOCKS даёт поток, а не инициализированный почтовый сеанс.
Для обычного SMTP, включая последующее обновление STARTTLS, сервер говорит первым:
SOCKS: connection to smtp.example.net:587 succeeds
server: 220 smtp.example.net ready
client: EHLO client.example.net
server: 250-smtp.example.net
server: 250-STARTTLS
server: 250 AUTH ...Это схематично; объявляемые расширения различаются. Само приветствие может занимать несколько строк: код ответа, за которым следует дефис, продолжает ответ, а последняя строка его завершает. Используйте всё приветствие до EHLO. Иначе клиент может прочитать старый 220, ожидая 250 от EHLO, и сбиться с ритма на исправном соединении.
У неявного TLS другой порядок: соединение SOCKS, рукопожатие TLS, затем приветствие SMTP внутри TLS. STARTTLS начинается с читаемого приветствия и EHLO, обновляет поток и после этого снова получает возможности.
Публичный конструктор обычно обрабатывает настройку сокета, сохранённые параметры соединения и сведения приветствия, начальный ответ и EHLO с запасным HELO там, где это уместно:
use Net::SMTP;
my $smtp = Net::SMTP->new(
'smtp.example.net',
Port => 587,
Hello => 'client.example.net',
Timeout => 30,
) or die "SMTP connection failed: $@";
$smtp->starttls()
or die "STARTTLS failed: " . $smtp->message;Этот публичный пример использует STARTTLS и не настраивает SOCKS. Имя сервера выбирает почтовое назначение; Hello задаёт идентичность SMTP клиента. Для неявного TLS используйте документированный параметр конструктора SSL и порт службы.
SendHello => 0 подавляет автоматический EHLO/HELO, а не чтение приветствия или построение транспорта. Вызов построчного читателя и затем hello() тоже не является документированной заменой инициализации: Net::Cmd относит свои низкоуровневые читатели ответов к защищённым методам подкласса.
Если SOCKS обязателен, выберите клиент с поддерживаемым интерфейсом SOCKS или поддерживайте интеграцию под конкретную версию Net::SMTP. Используйте приведённую выше последовательность как её контракт, а не копируйте закрытые поля. Отдельному адаптеру TCP тоже нужно осознанное управление идентичностью TLS: сертификат должен идентифицировать настоящую почтовую службу, а учётные данные прокси остаются отдельно от входа в SMTP.