frame.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. nDomain := len(addr.Domain())
  69. b = append(b, byte(protocol.AddressTypeDomain), byte(nDomain))
  70. b = append(b, addr.Domain()...)
  71. length += nDomain + 2
  72. }
  73. }
  74. serial.Uint16ToBytes(uint16(length), lengthBytes[:0])
  75. return length + 2, nil
  76. }
  77. }
  78. func ReadFrameFrom(b []byte) (*FrameMetadata, error) {
  79. if len(b) < 4 {
  80. return nil, newError("insufficient buffer: ", len(b))
  81. }
  82. f := &FrameMetadata{
  83. SessionID: serial.BytesToUint16(b[:2]),
  84. SessionStatus: SessionStatus(b[2]),
  85. Option: bitmask.Byte(b[3]),
  86. }
  87. b = b[4:]
  88. if f.SessionStatus == SessionStatusNew {
  89. network := TargetNetwork(b[0])
  90. port := net.PortFromBytes(b[1:3])
  91. addrType := protocol.AddressType(b[3])
  92. b = b[4:]
  93. var addr net.Address
  94. switch addrType {
  95. case protocol.AddressTypeIPv4:
  96. addr = net.IPAddress(b[0:4])
  97. b = b[4:]
  98. case protocol.AddressTypeIPv6:
  99. addr = net.IPAddress(b[0:16])
  100. b = b[16:]
  101. case protocol.AddressTypeDomain:
  102. nDomain := int(b[0])
  103. addr = net.DomainAddress(string(b[1 : 1+nDomain]))
  104. b = b[nDomain+1:]
  105. default:
  106. return nil, newError("unknown address type: ", addrType)
  107. }
  108. switch network {
  109. case TargetNetworkTCP:
  110. f.Target = net.TCPDestination(addr, port)
  111. case TargetNetworkUDP:
  112. f.Target = net.UDPDestination(addr, port)
  113. default:
  114. return nil, newError("unknown network type: ", network)
  115. }
  116. }
  117. return f, nil
  118. }