.NET 7+ मधील SOCKS5 प्रतिसाद: आंशिक TCP वाचन हाताळणे
सर्व्हरच्या TCP लेखन सीमांवर अवलंबून न राहता SOCKS5 आदेश प्रतिसादाचा स्थिर उपसर्ग आणि ATYP-अवलंबित प्रत्यय वाचा.
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 लहान वैयक्तिक वाचने हाताळतो आणि मागितलेल्या लांबीपूर्वी स्ट्रीम संपल्यास अपवाद फेकतो. अयशस्वी झाल्यास, अयशस्वी कनेक्शन त्याच्या मालकाच्या साफसफाईच्या मार्गाने टाकून द्या.
यशस्वी झाल्यास, प्रतिसादाच्या सीमेवर थांबा. त्यानंतरचे बाइट गंतव्य प्रोटोकॉलचे आहेत. मोठ्या अनुमानित वाचनाने अतिरिक्त बाइट जपले पाहिजेत, अनुप्रयोग स्ट्रीमची सुरुवात टाकून देवू नये.