’n SOCKS5-bediener skryf vier grepe afsonderlik, en die kliënt werk eers nadat daardie skrywes saamgevoeg is. Saamvoeging kan die tydsberekening verander, maar TCP belowe steeds nie een lees per skrywe nie.

Die kliënt het ’n antwoordontleder nodig. Ná metodekeuse en enige vereiste verifikasie begin ’n SOCKS5-opdragantwoord met vier grepe: weergawe, resultaat, gereserveerde greep en adrestipe. Die oorblywende lengte hang van daardie adrestipe af.

’n .NET 7+-ontleder wat net ’n suksesvolle CONNECT-antwoord hoef te verbruik, kan dit gebruik:

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);
}

Die laaste twee grepe is die gebinde poort. IPv4 het vier grepe nodig; IPv6 het sestien nodig; ’n domeinadres dra ’n lengtegreep voor die naam.

Voorsien ’n kansellasietoken met die beoogde onderhandelingstermyn. ReadExactlyAsync hanteer korter individuele lees en gooi ’n fout wanneer die stroom eindig voor die gevraagde lengte. By ’n fout moet die mislukte verbinding via sy eienaar se opruimingsroete weggegooi word.

By sukses stop by die antwoordgrens. Grepe daarna behoort aan die bestemmingprotokol. ’n Groter spekulatiewe lees moet die oortollige grepe bewaar eerder as om die begin van die toepassingstroom weg te gooi.

Verwante artikels