SOCKS5 svör í .NET 7+: að meðhöndla hlutbundnar TCP-lestrar
Lestu fasta forskeyti SOCKS5-skipanarsvarsins og viðskeytið sem fer eftir ATYP án þess að treysta á TCP-skrifmörk þjónsins.
SOCKS5-þjónn skrifar fjögur bæti í sitt hvoru lagi, og biðlarinn virkar aðeins eftir að þessum skrifum hefur verið steypt saman. Samsteypan getur breytt tímasetningu, en TCP lofar enn ekki einni lestri fyrir hvert skrif.
Biðlarinn þarf svarþáttara. Eftir aðferðarval og hvers kyns nauðsynlega auðkenningu hefst SOCKS5-skipanarsvar með fjórum bætum: útgáfa, niðurstaða, frátekið bæti og gerð vistfangs. Afgangslengdin fer eftir þeirri gerð vistfangs.
.NET 7+-þáttari sem þarf aðeins að neyta árangursríks CONNECT-svars getur notað:
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);
}
Síðustu tvö bætin eru bundna gáttin. IPv4 þarf fjögur bæti; IPv6 þarf sextán; lénsvistfang ber lengdarbæti fyrir nafnið.
Láttu af hendi afturköllunartákn með fyrirhuguðum samningstíma. ReadExactlyAsync meðhöndlar styttri einstakar lestrar og kastar undantekningu þegar straumurinn endar fyrir umbeðna lengd. Við mistök skal henda mistakaða tengingunni í gegnum hreinsunarleið eiganda hennar.
Við árangur skaltu stöðva á svar-mörkunum. Bætin á eftir tilheyra áfangastaðarprotokollinni. Stærri ímynduð lestur verður að varðveita umframbætin í stað þess að henda byrjun forritastraumsins.