.NET 7+ የSOCKS5 መልሶች፦ ከፊል የTCP ንባቦችን ማስተናገድ
የSOCKS5 ትዕዛዝ መልስ ቋሚ ቅድመ ክፍልን እና በATYP ላይ የተመሠረተውን ተከታይ ክፍል በአገልጋዩ የTCP ጽሕፈት ወሰን ላይ ሳይተማመን ያንብቡ።
የSOCKS5 አገልጋይ አራት ባይቶችን ለየብቻ ይጽፋል፣ ደንበኛው የሚሠራው እነዚያ ጽሕፈቶች አንድ ላይ ከተዋሃዱ በኋላ ብቻ ነው። ማዋሃድ ጊዜውን ሊቀይር ይችላል፣ ነገር ግን TCP አሁንም ለአንድ ጽሕፈት አንድ ንባብ ብቻ አይጠራም።
ደንበኛው የመልስ ተንታኝ ያስፈልገዋል። ከዘዴ ምርጫ እና ከሚያስፈልገው ማረጋገጫ በኋላ የSOCKS5 ትዕዛዝ መልስ በአራት ባይቶች ይጀምራል፦ ስሪት፣ ውጤት፣ የተከለለ ባይት እና የአድራሻ ዓይነት። ቀሪው ርዝመት በዚያ የአድራሻ ዓይነት ላይ ይመሠረታል።
አንድ .NET 7+ ተንታኝ የተሳካ CONNECT መልስን ብቻ መቅጠር ከፈለገ ይህን ሊጠቀም ይችላል፦
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 አጠር ያሉ የተናጠል ንባቦችን ያስተናግዳል እና ጅረቱ ከተጠየቀው ርዝመት በፊት ሲያበቃ ስህተት ይጥላል። በሽንፈት ጊዜ ያልተሳካውን ግንኙነት በባለቤቱ የማጽዳት መንገድ ያስወግዱ።
በስኬት ጊዜ በመልሱ ወሰን ላይ ያቁሙ። ከዚያ በኋላ ያሉት ባይቶች የመድረሻው ፕሮቶኮል ናቸው። ትልቅ ግምታዊ ንባብ የተረፈውን ባይት ማስቀመጥ አለበት እንጂ የመተግበሪያውን ጅረት መጀመሪያ መጣል የለበትም።