frame.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package mux
  2. import (
  3. "errors"
  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. )
  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. b = serial.Uint16ToBytes(uint16(0), b) // place holder for length
  57. b = serial.Uint16ToBytes(f.SessionID, b)
  58. b = append(b, byte(f.SessionStatus), byte(f.Option))
  59. length := 4
  60. if f.SessionStatus == SessionStatusNew {
  61. switch f.Target.Network {
  62. case net.Network_TCP:
  63. b = append(b, byte(TargetNetworkTCP))
  64. case net.Network_UDP:
  65. b = append(b, byte(TargetnetworkUDP))
  66. }
  67. length++
  68. b = serial.Uint16ToBytes(f.Target.Port.Value(), b)
  69. length += 2
  70. addr := f.Target.Address
  71. switch addr.Family() {
  72. case net.AddressFamilyIPv4:
  73. b = append(b, byte(AddressTypeIPv4))
  74. b = append(b, addr.IP()...)
  75. length += 5
  76. case net.AddressFamilyIPv6:
  77. b = append(b, byte(AddressTypeIPv6))
  78. b = append(b, addr.IP()...)
  79. length += 17
  80. case net.AddressFamilyDomain:
  81. nDomain := len(addr.Domain())
  82. b = append(b, byte(nDomain))
  83. b = append(b, addr.Domain()...)
  84. length += nDomain + 1
  85. }
  86. }
  87. return length + 2, nil
  88. }
  89. }
  90. func ReadFrameFrom(b []byte) (*FrameMetadata, error) {
  91. if len(b) < 4 {
  92. return nil, errors.New("Proxyman|Mux: Insufficient buffer.")
  93. }
  94. f := &FrameMetadata{
  95. SessionID: serial.BytesToUint16(b[:2]),
  96. SessionStatus: SessionStatus(b[2]),
  97. }
  98. b = b[4:]
  99. if f.SessionStatus == SessionStatusNew {
  100. network := TargetNetwork(b[0])
  101. port := net.PortFromBytes(b[1:3])
  102. addrType := AddressType(b[3])
  103. b = b[4:]
  104. var addr net.Address
  105. switch addrType {
  106. case AddressTypeIPv4:
  107. addr = net.IPAddress(b[0:4])
  108. b = b[4:]
  109. case AddressTypeIPv6:
  110. addr = net.IPAddress(b[0:16])
  111. b = b[16:]
  112. case AddressTypeDomain:
  113. nDomain := int(b[0])
  114. addr = net.DomainAddress(string(b[1 : 1+nDomain]))
  115. b = b[nDomain+1:]
  116. }
  117. switch network {
  118. case TargetNetworkTCP:
  119. f.Target = net.TCPDestination(addr, port)
  120. case TargetnetworkUDP:
  121. f.Target = net.UDPDestination(addr, port)
  122. }
  123. }
  124. return f, nil
  125. }