frame.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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/protocol"
  7. "v2ray.com/core/common/serial"
  8. )
  9. type SessionStatus byte
  10. const (
  11. SessionStatusNew SessionStatus = 0x01
  12. SessionStatusKeep SessionStatus = 0x02
  13. SessionStatusEnd SessionStatus = 0x03
  14. SessionStatusKeepAlive SessionStatus = 0x04
  15. )
  16. const (
  17. OptionData bitmask.Byte = 0x01
  18. )
  19. type TargetNetwork byte
  20. const (
  21. TargetNetworkTCP TargetNetwork = 0x01
  22. TargetNetworkUDP TargetNetwork = 0x02
  23. )
  24. /*
  25. Frame format
  26. 2 bytes - length
  27. 2 bytes - session id
  28. 1 bytes - status
  29. 1 bytes - option
  30. 1 byte - network
  31. 2 bytes - port
  32. n bytes - address
  33. */
  34. type FrameMetadata struct {
  35. Target net.Destination
  36. SessionID uint16
  37. Option bitmask.Byte
  38. SessionStatus SessionStatus
  39. }
  40. func (f FrameMetadata) AsSupplier() buf.Supplier {
  41. return func(b []byte) (int, error) {
  42. lengthBytes := b
  43. b = serial.Uint16ToBytes(uint16(0), b[:0]) // place holder for length
  44. b = serial.Uint16ToBytes(f.SessionID, b)
  45. b = append(b, byte(f.SessionStatus), byte(f.Option))
  46. length := 4
  47. if f.SessionStatus == SessionStatusNew {
  48. switch f.Target.Network {
  49. case net.Network_TCP:
  50. b = append(b, byte(TargetNetworkTCP))
  51. case net.Network_UDP:
  52. b = append(b, byte(TargetNetworkUDP))
  53. }
  54. length++
  55. b = serial.Uint16ToBytes(f.Target.Port.Value(), b)
  56. length += 2
  57. addr := f.Target.Address
  58. switch addr.Family() {
  59. case net.AddressFamilyIPv4:
  60. b = append(b, byte(protocol.AddressTypeIPv4))
  61. b = append(b, addr.IP()...)
  62. length += 5
  63. case net.AddressFamilyIPv6:
  64. b = append(b, byte(protocol.AddressTypeIPv6))
  65. b = append(b, addr.IP()...)
  66. length += 17
  67. case net.AddressFamilyDomain:
  68. domain := addr.Domain()
  69. nDomain := len(domain)
  70. if nDomain > 256 {
  71. nDomain = 256
  72. domain = domain[:256]
  73. }
  74. b = append(b, byte(protocol.AddressTypeDomain), byte(nDomain))
  75. b = append(b, 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 := protocol.AddressType(b[3])
  97. b = b[4:]
  98. var addr net.Address
  99. switch addrType {
  100. case protocol.AddressTypeIPv4:
  101. addr = net.IPAddress(b[0:4])
  102. b = b[4:]
  103. case protocol.AddressTypeIPv6:
  104. addr = net.IPAddress(b[0:16])
  105. b = b[16:]
  106. case protocol.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. }