protocol.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package vless
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "io"
  6. "github.com/sagernet/sing-vmess"
  7. "github.com/sagernet/sing/common"
  8. "github.com/sagernet/sing/common/buf"
  9. E "github.com/sagernet/sing/common/exceptions"
  10. M "github.com/sagernet/sing/common/metadata"
  11. "github.com/sagernet/sing/common/rw"
  12. )
  13. const (
  14. Version = 0
  15. FlowVision = "xtls-rprx-vision"
  16. )
  17. type Request struct {
  18. UUID [16]byte
  19. Command byte
  20. Destination M.Socksaddr
  21. Flow string
  22. }
  23. func ReadRequest(reader io.Reader) (*Request, error) {
  24. var request Request
  25. var version uint8
  26. err := binary.Read(reader, binary.BigEndian, &version)
  27. if err != nil {
  28. return nil, err
  29. }
  30. if version != Version {
  31. return nil, E.New("unknown version: ", version)
  32. }
  33. _, err = io.ReadFull(reader, request.UUID[:])
  34. if err != nil {
  35. return nil, err
  36. }
  37. var addonsLen uint8
  38. err = binary.Read(reader, binary.BigEndian, &addonsLen)
  39. if err != nil {
  40. return nil, err
  41. }
  42. if addonsLen > 0 {
  43. addonsBytes, err := rw.ReadBytes(reader, int(addonsLen))
  44. if err != nil {
  45. return nil, err
  46. }
  47. addons, err := readAddons(bytes.NewReader(addonsBytes))
  48. if err != nil {
  49. return nil, err
  50. }
  51. request.Flow = addons.Flow
  52. }
  53. err = binary.Read(reader, binary.BigEndian, &request.Command)
  54. if err != nil {
  55. return nil, err
  56. }
  57. if request.Command != vmess.CommandMux {
  58. request.Destination, err = vmess.AddressSerializer.ReadAddrPort(reader)
  59. if err != nil {
  60. return nil, err
  61. }
  62. }
  63. return &request, nil
  64. }
  65. type Addons struct {
  66. Flow string
  67. Seed string
  68. }
  69. func readAddons(reader io.Reader) (*Addons, error) {
  70. protoHeader, err := rw.ReadByte(reader)
  71. if err != nil {
  72. return nil, err
  73. }
  74. if protoHeader != 10 {
  75. return nil, E.New("unknown protobuf message header: ", protoHeader)
  76. }
  77. var addons Addons
  78. flowLen, err := rw.ReadUVariant(reader)
  79. if err != nil {
  80. if err == io.EOF {
  81. return &addons, nil
  82. }
  83. return nil, err
  84. }
  85. flowBytes, err := rw.ReadBytes(reader, int(flowLen))
  86. if err != nil {
  87. return nil, err
  88. }
  89. addons.Flow = string(flowBytes)
  90. seedLen, err := rw.ReadUVariant(reader)
  91. if err != nil {
  92. if err == io.EOF {
  93. return &addons, nil
  94. }
  95. return nil, err
  96. }
  97. seedBytes, err := rw.ReadBytes(reader, int(seedLen))
  98. if err != nil {
  99. return nil, err
  100. }
  101. addons.Seed = string(seedBytes)
  102. return &addons, nil
  103. }
  104. func WriteRequest(writer io.Writer, request Request, payload []byte) error {
  105. var requestLen int
  106. requestLen += 1 // version
  107. requestLen += 16 // uuid
  108. requestLen += 1 // protobuf length
  109. var addonsLen int
  110. if request.Flow != "" {
  111. addonsLen += 1 // protobuf header
  112. addonsLen += UvarintLen(uint64(len(request.Flow)))
  113. addonsLen += len(request.Flow)
  114. requestLen += addonsLen
  115. }
  116. requestLen += 1 // command
  117. if request.Command != vmess.CommandMux {
  118. requestLen += vmess.AddressSerializer.AddrPortLen(request.Destination)
  119. }
  120. requestLen += len(payload)
  121. _buffer := buf.StackNewSize(requestLen)
  122. defer common.KeepAlive(_buffer)
  123. buffer := common.Dup(_buffer)
  124. defer buffer.Release()
  125. common.Must(
  126. buffer.WriteByte(Version),
  127. common.Error(buffer.Write(request.UUID[:])),
  128. buffer.WriteByte(byte(addonsLen)),
  129. )
  130. if addonsLen > 0 {
  131. common.Must(buffer.WriteByte(10))
  132. binary.PutUvarint(buffer.Extend(UvarintLen(uint64(len(request.Flow)))), uint64(len(request.Flow)))
  133. common.Must(common.Error(buffer.Write([]byte(request.Flow))))
  134. }
  135. common.Must(
  136. buffer.WriteByte(request.Command),
  137. )
  138. if request.Command != vmess.CommandMux {
  139. common.Must(vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination))
  140. }
  141. common.Must1(buffer.Write(payload))
  142. return common.Error(writer.Write(buffer.Bytes()))
  143. }
  144. func WritePacketRequest(writer io.Writer, request Request, payload []byte) error {
  145. var requestLen int
  146. requestLen += 1 // version
  147. requestLen += 16 // uuid
  148. requestLen += 1 // protobuf length
  149. var addonsLen int
  150. /*if request.Flow != "" {
  151. addonsLen += 1 // protobuf header
  152. addonsLen += UvarintLen(uint64(len(request.Flow)))
  153. addonsLen += len(request.Flow)
  154. requestLen += addonsLen
  155. }*/
  156. requestLen += 1 // command
  157. requestLen += vmess.AddressSerializer.AddrPortLen(request.Destination)
  158. if len(payload) > 0 {
  159. requestLen += 2
  160. requestLen += len(payload)
  161. }
  162. _buffer := buf.StackNewSize(requestLen)
  163. defer common.KeepAlive(_buffer)
  164. buffer := common.Dup(_buffer)
  165. defer buffer.Release()
  166. common.Must(
  167. buffer.WriteByte(Version),
  168. common.Error(buffer.Write(request.UUID[:])),
  169. buffer.WriteByte(byte(addonsLen)),
  170. )
  171. if addonsLen > 0 {
  172. common.Must(buffer.WriteByte(10))
  173. binary.PutUvarint(buffer.Extend(UvarintLen(uint64(len(request.Flow)))), uint64(len(request.Flow)))
  174. common.Must(common.Error(buffer.Write([]byte(request.Flow))))
  175. }
  176. common.Must(
  177. buffer.WriteByte(vmess.CommandUDP),
  178. vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination),
  179. )
  180. if len(payload) > 0 {
  181. common.Must(
  182. binary.Write(buffer, binary.BigEndian, uint16(len(payload))),
  183. common.Error(buffer.Write(payload)),
  184. )
  185. }
  186. return common.Error(writer.Write(buffer.Bytes()))
  187. }
  188. func ReadResponse(reader io.Reader) error {
  189. version, err := rw.ReadByte(reader)
  190. if err != nil {
  191. return err
  192. }
  193. if version != Version {
  194. return E.New("unknown version: ", version)
  195. }
  196. protobufLength, err := rw.ReadByte(reader)
  197. if err != nil {
  198. return err
  199. }
  200. if protobufLength > 0 {
  201. err = rw.SkipN(reader, int(protobufLength))
  202. if err != nil {
  203. return err
  204. }
  205. }
  206. return nil
  207. }
  208. func UvarintLen(value uint64) int {
  209. var buffer [binary.MaxVarintLen64]byte
  210. return binary.PutUvarint(buffer[:], value)
  211. }