protocol.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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 += rw.UVariantLen(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.NewSize(requestLen)
  122. defer buffer.Release()
  123. common.Must(
  124. buffer.WriteByte(Version),
  125. common.Error(buffer.Write(request.UUID[:])),
  126. buffer.WriteByte(byte(addonsLen)),
  127. )
  128. if addonsLen > 0 {
  129. common.Must(buffer.WriteByte(10))
  130. binary.PutUvarint(buffer.Extend(rw.UVariantLen(uint64(len(request.Flow)))), uint64(len(request.Flow)))
  131. common.Must(common.Error(buffer.WriteString(request.Flow)))
  132. }
  133. common.Must(
  134. buffer.WriteByte(request.Command),
  135. )
  136. if request.Command != vmess.CommandMux {
  137. err := vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)
  138. if err != nil {
  139. return err
  140. }
  141. }
  142. common.Must1(buffer.Write(payload))
  143. return common.Error(writer.Write(buffer.Bytes()))
  144. }
  145. func EncodeRequest(request Request, buffer *buf.Buffer) error {
  146. var requestLen int
  147. requestLen += 1 // version
  148. requestLen += 16 // uuid
  149. requestLen += 1 // protobuf length
  150. var addonsLen int
  151. if request.Flow != "" {
  152. addonsLen += 1 // protobuf header
  153. addonsLen += rw.UVariantLen(uint64(len(request.Flow)))
  154. addonsLen += len(request.Flow)
  155. requestLen += addonsLen
  156. }
  157. requestLen += 1 // command
  158. if request.Command != vmess.CommandMux {
  159. requestLen += vmess.AddressSerializer.AddrPortLen(request.Destination)
  160. }
  161. common.Must(
  162. buffer.WriteByte(Version),
  163. common.Error(buffer.Write(request.UUID[:])),
  164. buffer.WriteByte(byte(addonsLen)),
  165. )
  166. if addonsLen > 0 {
  167. common.Must(buffer.WriteByte(10))
  168. binary.PutUvarint(buffer.Extend(rw.UVariantLen(uint64(len(request.Flow)))), uint64(len(request.Flow)))
  169. common.Must(common.Error(buffer.WriteString(request.Flow)))
  170. }
  171. common.Must(
  172. buffer.WriteByte(request.Command),
  173. )
  174. if request.Command != vmess.CommandMux {
  175. err := vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)
  176. if err != nil {
  177. return err
  178. }
  179. }
  180. return nil
  181. }
  182. func RequestLen(request Request) int {
  183. var requestLen int
  184. requestLen += 1 // version
  185. requestLen += 16 // uuid
  186. requestLen += 1 // protobuf length
  187. var addonsLen int
  188. if request.Flow != "" {
  189. addonsLen += 1 // protobuf header
  190. addonsLen += rw.UVariantLen(uint64(len(request.Flow)))
  191. addonsLen += len(request.Flow)
  192. requestLen += addonsLen
  193. }
  194. requestLen += 1 // command
  195. if request.Command != vmess.CommandMux {
  196. requestLen += vmess.AddressSerializer.AddrPortLen(request.Destination)
  197. }
  198. return requestLen
  199. }
  200. func WritePacketRequest(writer io.Writer, request Request, payload []byte) error {
  201. var requestLen int
  202. requestLen += 1 // version
  203. requestLen += 16 // uuid
  204. requestLen += 1 // protobuf length
  205. var addonsLen int
  206. /*if request.Flow != "" {
  207. addonsLen += 1 // protobuf header
  208. addonsLen += rw.UVariantLen(uint64(len(request.Flow)))
  209. addonsLen += len(request.Flow)
  210. requestLen += addonsLen
  211. }*/
  212. requestLen += 1 // command
  213. requestLen += vmess.AddressSerializer.AddrPortLen(request.Destination)
  214. if len(payload) > 0 {
  215. requestLen += 2
  216. requestLen += len(payload)
  217. }
  218. buffer := buf.NewSize(requestLen)
  219. defer buffer.Release()
  220. common.Must(
  221. buffer.WriteByte(Version),
  222. common.Error(buffer.Write(request.UUID[:])),
  223. buffer.WriteByte(byte(addonsLen)),
  224. )
  225. if addonsLen > 0 {
  226. common.Must(buffer.WriteByte(10))
  227. binary.PutUvarint(buffer.Extend(rw.UVariantLen(uint64(len(request.Flow)))), uint64(len(request.Flow)))
  228. common.Must(common.Error(buffer.WriteString(request.Flow)))
  229. }
  230. common.Must(buffer.WriteByte(vmess.CommandUDP))
  231. err := vmess.AddressSerializer.WriteAddrPort(buffer, request.Destination)
  232. if err != nil {
  233. return err
  234. }
  235. if len(payload) > 0 {
  236. common.Must(
  237. binary.Write(buffer, binary.BigEndian, uint16(len(payload))),
  238. common.Error(buffer.Write(payload)),
  239. )
  240. }
  241. return common.Error(writer.Write(buffer.Bytes()))
  242. }
  243. func ReadResponse(reader io.Reader) error {
  244. version, err := rw.ReadByte(reader)
  245. if err != nil {
  246. return err
  247. }
  248. if version != Version {
  249. return E.New("unknown version: ", version)
  250. }
  251. protobufLength, err := rw.ReadByte(reader)
  252. if err != nil {
  253. return err
  254. }
  255. if protobufLength > 0 {
  256. err = rw.SkipN(reader, int(protobufLength))
  257. if err != nil {
  258. return err
  259. }
  260. }
  261. return nil
  262. }