ການຕອບສະໜອງ SOCKS5 ໃນ .NET 7+: ຮັບມືກັບການອ່ານ TCP ບາງສ່ວນ
ອ່ານຄຳນຳໜ້າຄົງທີ່ຂອງການຕອບສະໜອງຄຳສັ່ງ SOCKS5 ແລະ ຄຳຕາມຫຼັງທີ່ຂຶ້ນກັບ ATYP ໂດຍບໍ່ອີງໃສ່ຂອບເຂດການຂຽນ TCP ຂອງເຊີບເວີ.
ເຊີບເວີ SOCKS5 ຂຽນສີ່ໄບຕແຍກກັນ ແລະ ລູກຄ້າຈະເຮັດວຽກຫຼັງຈາກການຂຽນເຫຼົ່ານັ້ນຖືກລວມເຂົ້າກັນແລ້ວເທົ່ານັ້ນ. ການລວມອາດປ່ຽນເວລາ ແຕ່ TCP ຍັງບໍ່ຮັບປະກັນການອ່ານໜຶ່ງຄັ້ງຕໍ່ການຂຽນໜຶ່ງຄັ້ງ.
ລູກຄ້າຕ້ອງການຕົວແຍກການຕອບສະໜອງ. ຫຼັງຈາກເລືອກວິທີ ແລະ ການກວດສອບຕົວຕົນທີ່ຈຳເປັນ, ການຕອບສະໜອງຄຳສັ່ງ SOCKS5 ເລີ່ມດ້ວຍສີ່ໄບຕ: ສະບັບ, ຜົນ, ໄບຕສຳຮອງ ແລະ ປະເພດທີ່ຢູ່. ຄວາມຍາວທີ່ເຫຼືອຂຶ້ນກັບປະເພດທີ່ຢູ່ນັ້ນ.
ຕົວແຍກ .NET 7+ ທີ່ຕ້ອງການພຽງແຕ່ໃຊ້ການຕອບສະໜອງ CONNECT ທີ່ສຳເລັດສາມາດໃຊ້:
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 ຮັບມືກັບການອ່ານແຕ່ລະຄັ້ງທີ່ສັ້ນກວ່າ ແລະ ໂຍນຂໍ້ຜິດພາດເມື່ອສະຕຣີມສິ້ນສຸດກ່ອນຄວາມຍາວທີ່ຮ້ອງຂໍ. ຖ້າລົ້ມເຫຼວ, ຖິ້ມການເຊື່ອມຕໍ່ທີ່ລົ້ມເຫຼວຜ່ານເສັ້ນທາງເຮັດຄວາມສະອາດຂອງເຈົ້າຂອງມັນ.
ຖ້າສຳເລັດ, ຢຸດຢູ່ຂອບເຂດຂອງການຕອບສະໜອງ. ໄບຕຫຼັງຈາກນັ້ນເປັນຂອງໂປຣໂຕຄອນປາຍທາງ. ການອ່ານຄາດຄະເນທີ່ໃຫຍ່ກວ່າຕ້ອງເກັບໄບຕສ່ວນເກີນ ບໍ່ແມ່ນຖິ້ມຕອນເລີ່ມຂອງສະຕຣີມແອັບພລິເຄຊັນ.