private void AuthMethodRecvCallback() { { // Parse client methods ClientFromBuffer.RequireRead(ClientFromBuffer.Size, out ArraySegment <byte> _buffer); var buffer = (IList <byte>)_buffer; if (buffer[0] != 0x5) { ConnectionReject(true); return; } int nMethods = buffer[1]; var authMethodLen = nMethods + 2; if (authMethodLen < buffer.Count) { ReadAtLeast(authMethodLen, AuthMethodRecvCallback); return; } var hasNoAuthRequired = false; var j = 0; for (var i = 2; j < nMethods; i++, j++) { if (buffer[i] == 0x0) { hasNoAuthRequired = true; break; } } ClientFromBuffer.ConfirmRead(authMethodLen); if (!hasNoAuthRequired) { ConnectionReject(false); return; } } { // Select method ClientToBuffer.Clear(); ClientToBuffer.RequireWrite(2, true, false, out ArraySegment <byte> _buffer); var buffer = (IList <byte>)_buffer; buffer[0] = 0x5; buffer[1] = 0x0; ClientToBuffer.ConfirmWrite(2); Send(ClientToBuffer.Size, AuthMethodSendCallback); } }
private void OnRequestFullyReadCallback() { ClientFromBuffer.RequireRead(ClientFromBuffer.Size, out ArraySegment <byte> _buffer); var buffer = (IList <byte>)_buffer; int cmd = buffer[1]; int atyp = buffer[3]; string dstAddr; int dstPort; int headerLen; switch (atyp) { case 1: // IPv4 address, 4 bytes dstAddr = new IPAddress(buffer.Skip(4).Take(4).ToArray()).ToString(); dstPort = (buffer[4 + 4] << 8) + buffer[4 + 4 + 1]; headerLen = 4 + 4 + 2; break; case 3: // domain name, length + str int len = buffer[4]; dstAddr = Encoding.UTF8.GetString(_buffer.Array, _buffer.Offset + 4 + 1, len); dstPort = (buffer[4 + 1 + len] << 8) + buffer[4 + 1 + len + 1]; headerLen = 4 + 1 + len + 2; break; case 4: // IPv6 address, 16 bytes dstAddr = $"[{new IPAddress(buffer.Skip(4).Take(16).ToArray())}]"; dstPort = (buffer[4 + 16] << 8) + buffer[4 + 16 + 1]; headerLen = 4 + 16 + 2; break; default: Debug.WriteLine("Unsupported ATYP=" + atyp); Stop(); return; } ClientFromBuffer.ConfirmRead(headerLen); Debug.WriteLine($"connect to {dstAddr}:{dstPort}"); // Handle cmd switch (cmd) { case 1: Debug.WriteLine("CMD=" + cmd); _server.OnClientRequestConnect(dstAddr, dstPort); break; case 3: Debug.WriteLine("Unsupported CMD=" + cmd); Reply(ServerReply.CommandNotSupported, Stop); break; default: Debug.WriteLine("Unsupported CMD=" + cmd); Reply(ServerReply.CommandNotSupported, Stop); break; } }