ഒരു 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 കൈകാര്യം ചെയ്യുന്നു, ആവശ്യപ്പെട്ട നീളത്തിന് മുമ്പ് സ്ട്രീം അവസാനിച്ചാൽ അത് ഒരു എക്സെപ്ഷൻ എറിയുന്നു. പരാജയപ്പെട്ടാൽ, പരാജയപ്പെട്ട കണക്ഷൻ അതിന്റെ ഉടമയുടെ ക്ലീനപ്പ് പാതയിലൂടെ ഒഴിവാക്കുക.

വിജയിച്ചാൽ, മറുപടിയുടെ അതിരിൽ നിർത്തുക. അതിന് ശേഷമുള്ള ബൈറ്റുകൾ ലക്ഷ്യ പ്രോട്ടോക്കോളിന്റേതാണ്. വലിയ സ്പെക്കുലേറ്റീവ് വായന അധിക ബൈറ്റുകൾ സൂക്ഷിക്കണം, ആപ്ലിക്കേഷൻ സ്ട്രീമിന്റെ തുടക്കം വലിച്ചെറിയരുത്.

അനുബന്ധ ലേഖനങ്ങൾ