frame.go 3.3 KB

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