SOCKS5 erantzunak .NET 7+ bertsioan: TCP irakurketa partzialak kudeatzea
Irakurri SOCKS5 komando-erantzunaren aurrizki finkoa eta ATYP-ren araberako atzizkia, zerbitzariaren TCP idazketa-mugei erreparatu gabe.
SOCKS5 zerbitzari batek lau byte modu bereizian idazten ditu, eta bezeroak idazketa horiek bat egin ondoren bakarrik funtzionatzen du. Bat egiteak denbora alda dezake, baina TCPk oraindik ez du idazketa bakoitzeko irakurketa bat agintzen.
Bezeroak erantzun-analizatzaile bat behar du. Metodoa hautatu eta beharrezko autentifikazioa egin ondoren, SOCKS5 komando-erantzuna lau byterekin hasten da: bertsioa, emaitza, byte erreserbatua eta helbide-mota. Gainerako luzera helbide-mota horren araberakoa da.
CONNECT erantzun arrakastatsu bat soilik kontsumitu behar duen .NET 7+ analizatzaileak hau erabil dezake:
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);
}
Azken bi byteak lotutako ataka dira. IPv4k lau byte behar ditu; IPv6k hamasei; domeinu-helbide batek luzera-byte bat darama izenaren aurretik.
Eman ezeztatze-token bat negoziazio-epearekin. ReadExactlyAsync-ek irakurketa indibidual laburragoak kudeatzen ditu eta salbuespena botatzen du fluxua eskatutako luzera baino lehen amaitzen bada. Hutsegitean, baztertu huts egindako konexioa bere jabearen garbiketa-bidearen bidez.
Arrakastan, gelditu erantzunaren mugan. Haren ondorengo byteak helmugako protokoloarenak dira. Irakurketa espekulatibo handiago batek soberako byteak gorde behar ditu, aplikazio-fluxuaren hasiera botaz egin beharrean.