In SOCKS5-tsjinner skriuwt fjouwer bytes apart, en de klant wurket pas nei't dy skriuwsels kombinearre binne. Kombinearjen kin de timing feroarje, mar TCP belooft noch altyd net ien lêzing per skriuwsels.

De klant hat in antwurd-parser nedich. Nei metoadekar en alle fereaske autentikaasje begjint in SOCKS5-kommando-antwurd mei fjouwer bytes: ferzje, resultaat, reservearre byte en adrestype. De oerbliuwende lingte hinget fan dat adrestype ôf.

In .NET 7+-parser dy't allinnich in slagge CONNECT-antwurd konsumearje moat, kin dit brûke:

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

De lêste twa bytes binne de bûne poarte. IPv4 hat fjouwer bytes nedich; IPv6 hat sechstjin nedich; in domeinadres draacht in lingtebyte foar de namme.

Jou in annulearringstoken mei de bedoelde ûnderhannelingstermyn. ReadExactlyAsync behannelet koartere yndividuele lêzingen en smyt in útsûndering as de stream einiget foar de oanfrege lingte. By mislearring moat de mislearre ferbining fia it oprommingspaad fan syn eigner fuortgoaid wurde.

By súkses stopje by de antwurdgrins. Bytes dêrnei hearre by it bestimmingsprotokol. In grutter spekulatyf lêzen moat de oerbliuwende bytes bewarje ynstee fan it begjin fan 'e applikaasjestream fuort te smiten.

Relatearre artikelen