.NET 7+ ішіндегі SOCKS5 жауаптары: жартылай TCP оқуларды өңдеу
SOCKS5 пәрмені жауабының тұрақты префиксін және ATYP-ке тәуелді суффиксін сервердің TCP жазу шекараларына сенбей оқыңыз.
SOCKS5 сервері төрт байтты бөлек жазады, ал клиент бұл жазулар біріккеннен кейін ғана жұмыс істейді. Біріктіру уақытты өзгертуі мүмкін, бірақ TCP әлі де әр жазбаға бір оқу уәде етпейді.
Клиентке жауап талдағышы қажет. Әдісті таңдаудан және қажетті аутентификациядан кейін SOCKS5 пәрменінің жауабы төрт байттан басталады: нұсқа, нәтиже, резервтелген байт және мекенжай түрі. Қалған ұзындық сол мекенжай түріне байланысты.
Тек сәтті CONNECT жауабын тұтыну қажет .NET 7+ талдағышы мынаны қолдана алады:
static async Task ReadConnectReply(Stream stream, CancellationToken ct)
{
byte[] prefix = new byte[4];
await stream.ReadExactlyAsync(prefix, ct);
if (prefix[0] != 5 || prefix[2] != 0)
throw new IOException("Invalid SOCKS5 reply");
if (prefix[1] != 0)
throw new IOException($"SOCKS5 request failed: {prefix[1]}");
int remaining;
switch (prefix[3])
{
case 1: remaining = 4 + 2; break;
case 4: remaining = 16 + 2; break;
case 3:
byte[] length = new byte[1];
await stream.ReadExactlyAsync(length, ct);
remaining = length[0] + 2;
break;
default:
throw new IOException("Unknown SOCKS5 address type");
}
await stream.ReadExactlyAsync(new byte[remaining], ct);
}
Соңғы екі байт — байланған порт. IPv4 төрт байт қажет етеді; IPv6 он алты байт қажет етеді; домен мекенжайы атауының алдында ұзындық байтын алып жүреді.
Күтілетін келіссөз мерзімімен жою токенін беріңіз. ReadExactlyAsync қысқарақ жеке оқуларды өңдейді және ағын сұралған ұзындыққа жетпей бітсе, ерекшелік лақтырады. Сәтсіздік кезінде сәтсіз қосылымды оның иесінің тазарту жолымен жойыңыз.
Сәттілік кезінде жауап шекарасында тоқтаңыз. Одан кейінгі байттар мақсаттық протоколға тиесілі. Неғұрлым үлкен болжамды оқу қосымша байттарды сақтауы керек, қосымша ағынының басын тастамауы керек.