frame.go 3.1 KB

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