SOCKS5 server zapisuje četiri bajta odvojeno, a klijent radi tek nakon što se ti upisi spoje. Spajanje može promeniti vreme, ali TCP još uvek ne obećava jedno čitanje po upisu.

Klijentu treba parser odgovora. Nakon izbora metode i bilo koje potrebne autentifikacije, odgovor SOCKS5 komande počinje sa četiri bajta: verzija, rezultat, rezervisani bajt i tip adrese. Preostala dužina zavisi od tog tipa adrese.

Parser za .NET 7+ koji treba da potroši samo uspešan CONNECT odgovor može da koristi:

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

Poslednja dva bajta su vezani port. IPv4 zahteva četiri bajta; IPv6 šesnaest; adresa domena nosi bajt dužine pre imena.

Dostavite token za otkazivanje sa predviđenim rokom pregovaranja. ReadExactlyAsync obrađuje kraća pojedinačna čitanja i baca izuzetak kada tok završi pre tražene dužine. U slučaju neuspeha odbacite neuspešnu vezu kroz putanju čišćenja njenog vlasnika.

Na uspehu se zaustavite na granici odgovora. Bajtovi nakon nje pripadaju protokolu odredišta. Veće spekulativno čitanje mora sačuvati višak bajtova umesto da odbaci početak aplikacionog toka.

Povezani članci