frame.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package mux
  2. import (
  3. "errors"
  4. "v2ray.com/core/common/buf"
  5. "v2ray.com/core/common/net"
  6. "v2ray.com/core/common/serial"
  7. )
  8. type SessionStatus byte
  9. const (
  10. SessionStatusNew SessionStatus = 0x01
  11. SessionStatusKeep SessionStatus = 0x02
  12. SessionStatusEnd SessionStatus = 0x03
  13. )
  14. type TargetNetwork byte
  15. const (
  16. TargetNetworkTCP TargetNetwork = 0x01
  17. TargetnetworkUDP TargetNetwork = 0x02
  18. )
  19. type AddressType byte
  20. const (
  21. AddressTypeIPv4 AddressType = 0x01
  22. AddressTypeDomain AddressType = 0x02
  23. AddressTypeIPv6 AddressType = 0x03
  24. )
  25. /*
  26. Frame format
  27. 2 bytes - length
  28. 2 bytes - session id
  29. 1 bytes - status
  30. 1 bytes - reserved
  31. 1 byte - network
  32. 2 bytes - port
  33. n bytes - address
  34. */
  35. type FrameMetadata struct {
  36. SessionID uint16
  37. SessionStatus SessionStatus
  38. Target net.Destination
  39. }
  40. func (f FrameMetadata) AsSupplier() buf.Supplier {
  41. return func(b []byte) (int, error) {
  42. b = serial.Uint16ToBytes(uint16(0), b) // place holder for length
  43. b = serial.Uint16ToBytes(f.SessionID, b)
  44. b = append(b, byte(f.SessionStatus), 0 /* reserved */)
  45. length := 4
  46. if f.SessionStatus == SessionStatusNew {
  47. switch f.Target.Network {
  48. case net.Network_TCP:
  49. b = append(b, byte(TargetNetworkTCP))
  50. case net.Network_UDP:
  51. b = append(b, byte(TargetnetworkUDP))
  52. }
  53. length++
  54. b = serial.Uint16ToBytes(f.Target.Port.Value(), b)
  55. length += 2
  56. addr := f.Target.Address
  57. switch addr.Family() {
  58. case net.AddressFamilyIPv4:
  59. b = append(b, byte(AddressTypeIPv4))
  60. b = append(b, addr.IP()...)
  61. length += 5
  62. case net.AddressFamilyIPv6:
  63. b = append(b, byte(AddressTypeIPv6))
  64. b = append(b, addr.IP()...)
  65. length += 17
  66. case net.AddressFamilyDomain:
  67. nDomain := len(addr.Domain())
  68. b = append(b, byte(nDomain))
  69. b = append(b, addr.Domain()...)
  70. length += nDomain + 1
  71. }
  72. }
  73. return length + 2, nil
  74. }
  75. }
  76. func ReadFrameFrom(b []byte) (*FrameMetadata, error) {
  77. if len(b) < 4 {
  78. return nil, errors.New("Proxyman|Mux: Insufficient buffer.")
  79. }
  80. f := &FrameMetadata{
  81. SessionID: serial.BytesToUint16(b[:2]),
  82. SessionStatus: SessionStatus(b[2]),
  83. }
  84. b = b[4:]
  85. if f.SessionStatus == SessionStatusNew {
  86. network := TargetNetwork(b[0])
  87. port := net.PortFromBytes(b[1:3])
  88. addrType := AddressType(b[3])
  89. b = b[4:]
  90. var addr net.Address
  91. switch addrType {
  92. case AddressTypeIPv4:
  93. addr = net.IPAddress(b[0:4])
  94. b = b[4:]
  95. case AddressTypeIPv6:
  96. addr = net.IPAddress(b[0:16])
  97. b = b[16:]
  98. case AddressTypeDomain:
  99. nDomain := int(b[0])
  100. addr = net.DomainAddress(string(b[1 : 1+nDomain]))
  101. b = b[nDomain+1:]
  102. }
  103. switch network {
  104. case TargetNetworkTCP:
  105. f.Target = net.TCPDestination(addr, port)
  106. case TargetnetworkUDP:
  107. f.Target = net.UDPDestination(addr, port)
  108. }
  109. }
  110. return f, nil
  111. }