Запит з'єднання SOCKS4 виконується успішно, але застосунок так і не бачить початкового привітання сервера. Одне з місць, куди варто подивитися, — перше читання конектора. Читання шістнадцяти байтів завелике для восьмибайтової відповіді SOCKS4.

Поле відповідіБайти
Поле версії відповіді1
Код результату1
Поле порту2
Поле адреси4

Код результату 0x5a означає, що запит дозволено. SOCKS4a змінює те, як запит несе ім'я хоста; він не перетворює відповідь на шістнадцять байтів.

Після відповіді той самий потік TCP несе протокол призначення. Поштовий сервер може надіслати привітання одразу. Тому читання, що забирає шістнадцять доступних байтів, може захопити повну відповідь проксі та перші вісім байтів цього привітання. Якщо далі поки нічого немає, завелике блокуюче читання, навпаки, додасть зайве очікування.

Точна довжина — обов'язок парсера

Одноразовий запит восьми байтів не доводить, що вісім байтів надійшли. Читання з потоку можуть повернути менше. Зберіть рівно довжину відповіді в межах терміну, зупиніться на закритому або збійному потоці, перевірте відповідь і залиште наступні байти застосунку.

Якщо конектор використовує більше буферизоване читання, збережіть усе після межі та передайте наступному споживачеві. Відкидання надлишку — та сама втрата даних з іншим розміром читання.

SOCKS5 потребує власного парсера. Довжина адреси в його відповіді може різнитися залежно від типу адреси. Заміна кожного читання проксі фіксованим читанням восьми байтів виправила б один протокол, але зламала б інший.

Схожі статті