You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Socks5RequestReplyMessage.cs 2.4 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using System;
  2. using System.Diagnostics;
  3. using System.Net;
  4. namespace Shadowsocks.Protocol.Socks5
  5. {
  6. public class Socks5RequestReplyMessageBase : Socks5Message
  7. {
  8. // 5 cmdOrReply 0 aType [addr] port
  9. protected byte CmdByte;
  10. public EndPoint EndPoint =new IPEndPoint(IPAddress.Any, 0);
  11. public override int Serialize(Memory<byte> buffer)
  12. {
  13. var addrLen = NeededBytes(EndPoint);
  14. if (buffer.Length < addrLen + 3) throw Util.BufferTooSmall(addrLen + 3, buffer.Length, nameof(buffer));
  15. buffer.Span[0] = 5;
  16. buffer.Span[1] = CmdByte;
  17. buffer.Span[2] = 0;
  18. return SerializeAddress(buffer[3..], EndPoint) + 3;
  19. }
  20. public override (bool success, int length) TryLoad(ReadOnlyMemory<byte> buffer)
  21. {
  22. if (buffer.Length < 4) return (false, 4);
  23. if (buffer.Span[0] != 5 || buffer.Span[2] != 0) return (false, 0);
  24. if (buffer.Span[3] == 3 && buffer.Length < 5) return (false, 5);
  25. var req = buffer.Span[3] switch
  26. {
  27. AddressIPv4 => 10,
  28. AddressDomain => buffer.Span[4] + 7,
  29. AddressIPv6 => 22,
  30. _ => 0,
  31. };
  32. if (req == 0) return (false, 0);
  33. if (buffer.Length < req) return (false, req);
  34. (var state, var len) = TryParseAddress(buffer[3..], out var ep);
  35. Debug.Assert(state);
  36. Debug.Assert(len == req - 3);
  37. CmdByte = buffer.Span[1];
  38. EndPoint = ep;
  39. return (true, req);
  40. }
  41. public override bool Equals(IProtocolMessage other)
  42. {
  43. if (other is null) return false;
  44. if (ReferenceEquals(this, other)) return true;
  45. if (other.GetType() != GetType()) return false;
  46. var msg = (Socks5RequestReplyMessageBase) other;
  47. return CmdByte == msg.CmdByte && EndPoint.Equals(msg.EndPoint);
  48. }
  49. }
  50. public class Socks5ReplyMessage : Socks5RequestReplyMessageBase
  51. {
  52. public byte Reply
  53. {
  54. get => CmdByte;
  55. set => CmdByte = value;
  56. }
  57. }
  58. public class Socks5RequestMessage : Socks5RequestReplyMessageBase
  59. {
  60. public byte Command
  61. {
  62. get => CmdByte;
  63. set => CmdByte = value;
  64. }
  65. }
  66. }