frame.go 3.2 KB

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