profile_import.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. package libbox
  2. import (
  3. "bufio"
  4. "bytes"
  5. "compress/gzip"
  6. "encoding/binary"
  7. "io"
  8. E "github.com/sagernet/sing/common/exceptions"
  9. "github.com/sagernet/sing/common/varbin"
  10. )
  11. func EncodeChunkedMessage(data []byte) []byte {
  12. var buffer bytes.Buffer
  13. binary.Write(&buffer, binary.BigEndian, uint16(len(data)))
  14. buffer.Write(data)
  15. return buffer.Bytes()
  16. }
  17. func DecodeLengthChunk(data []byte) int32 {
  18. return int32(binary.BigEndian.Uint16(data))
  19. }
  20. const (
  21. MessageTypeError = iota
  22. MessageTypeProfileList
  23. MessageTypeProfileContentRequest
  24. MessageTypeProfileContent
  25. )
  26. type ErrorMessage struct {
  27. Message string
  28. }
  29. func (e *ErrorMessage) Encode() []byte {
  30. var buffer bytes.Buffer
  31. buffer.WriteByte(MessageTypeError)
  32. writeString(&buffer, e.Message)
  33. return buffer.Bytes()
  34. }
  35. func DecodeErrorMessage(data []byte) (*ErrorMessage, error) {
  36. reader := bytes.NewReader(data)
  37. messageType, err := reader.ReadByte()
  38. if err != nil {
  39. return nil, err
  40. }
  41. if messageType != MessageTypeError {
  42. return nil, E.New("invalid message")
  43. }
  44. var message ErrorMessage
  45. message.Message, err = readString(reader)
  46. if err != nil {
  47. return nil, err
  48. }
  49. return &message, nil
  50. }
  51. const (
  52. ProfileTypeLocal int32 = iota
  53. ProfileTypeiCloud
  54. ProfileTypeRemote
  55. )
  56. type ProfilePreview struct {
  57. ProfileID int64
  58. Name string
  59. Type int32
  60. }
  61. type ProfilePreviewIterator interface {
  62. Next() *ProfilePreview
  63. HasNext() bool
  64. }
  65. type ProfileEncoder struct {
  66. profiles []ProfilePreview
  67. }
  68. func (e *ProfileEncoder) Append(profile *ProfilePreview) {
  69. e.profiles = append(e.profiles, *profile)
  70. }
  71. func (e *ProfileEncoder) Encode() []byte {
  72. var buffer bytes.Buffer
  73. buffer.WriteByte(MessageTypeProfileList)
  74. binary.Write(&buffer, binary.BigEndian, uint16(len(e.profiles)))
  75. for _, preview := range e.profiles {
  76. binary.Write(&buffer, binary.BigEndian, preview.ProfileID)
  77. writeString(&buffer, preview.Name)
  78. binary.Write(&buffer, binary.BigEndian, preview.Type)
  79. }
  80. return buffer.Bytes()
  81. }
  82. type ProfileDecoder struct {
  83. profiles []*ProfilePreview
  84. }
  85. func (d *ProfileDecoder) Decode(data []byte) error {
  86. reader := bytes.NewReader(data)
  87. messageType, err := reader.ReadByte()
  88. if err != nil {
  89. return err
  90. }
  91. if messageType != MessageTypeProfileList {
  92. return E.New("invalid message")
  93. }
  94. var profileCount uint16
  95. err = binary.Read(reader, binary.BigEndian, &profileCount)
  96. if err != nil {
  97. return err
  98. }
  99. for i := 0; i < int(profileCount); i++ {
  100. var profile ProfilePreview
  101. err = binary.Read(reader, binary.BigEndian, &profile.ProfileID)
  102. if err != nil {
  103. return err
  104. }
  105. profile.Name, err = readString(reader)
  106. if err != nil {
  107. return err
  108. }
  109. err = binary.Read(reader, binary.BigEndian, &profile.Type)
  110. if err != nil {
  111. return err
  112. }
  113. d.profiles = append(d.profiles, &profile)
  114. }
  115. return nil
  116. }
  117. func (d *ProfileDecoder) Iterator() ProfilePreviewIterator {
  118. return newIterator(d.profiles)
  119. }
  120. type ProfileContentRequest struct {
  121. ProfileID int64
  122. }
  123. func (r *ProfileContentRequest) Encode() []byte {
  124. var buffer bytes.Buffer
  125. buffer.WriteByte(MessageTypeProfileContentRequest)
  126. binary.Write(&buffer, binary.BigEndian, r.ProfileID)
  127. return buffer.Bytes()
  128. }
  129. func DecodeProfileContentRequest(data []byte) (*ProfileContentRequest, error) {
  130. reader := bytes.NewReader(data)
  131. messageType, err := reader.ReadByte()
  132. if err != nil {
  133. return nil, err
  134. }
  135. if messageType != MessageTypeProfileContentRequest {
  136. return nil, E.New("invalid message")
  137. }
  138. var request ProfileContentRequest
  139. err = binary.Read(reader, binary.BigEndian, &request.ProfileID)
  140. if err != nil {
  141. return nil, err
  142. }
  143. return &request, nil
  144. }
  145. type ProfileContent struct {
  146. Name string
  147. Type int32
  148. Config string
  149. RemotePath string
  150. AutoUpdate bool
  151. AutoUpdateInterval int32
  152. LastUpdated int64
  153. }
  154. func (c *ProfileContent) Encode() []byte {
  155. buffer := new(bytes.Buffer)
  156. buffer.WriteByte(MessageTypeProfileContent)
  157. buffer.WriteByte(1)
  158. gWriter := gzip.NewWriter(buffer)
  159. writer := bufio.NewWriter(gWriter)
  160. writeStringBuffered(writer, c.Name)
  161. binary.Write(writer, binary.BigEndian, c.Type)
  162. writeStringBuffered(writer, c.Config)
  163. if c.Type != ProfileTypeLocal {
  164. writeStringBuffered(writer, c.RemotePath)
  165. }
  166. if c.Type == ProfileTypeRemote {
  167. binary.Write(writer, binary.BigEndian, c.AutoUpdate)
  168. binary.Write(writer, binary.BigEndian, c.AutoUpdateInterval)
  169. binary.Write(writer, binary.BigEndian, c.LastUpdated)
  170. }
  171. writer.Flush()
  172. gWriter.Flush()
  173. gWriter.Close()
  174. return buffer.Bytes()
  175. }
  176. func DecodeProfileContent(data []byte) (*ProfileContent, error) {
  177. reader := bytes.NewReader(data)
  178. messageType, err := reader.ReadByte()
  179. if err != nil {
  180. return nil, err
  181. }
  182. if messageType != MessageTypeProfileContent {
  183. return nil, E.New("invalid message")
  184. }
  185. version, err := reader.ReadByte()
  186. if err != nil {
  187. return nil, err
  188. }
  189. gReader, err := gzip.NewReader(reader)
  190. if err != nil {
  191. return nil, E.Cause(err, "unsupported profile")
  192. }
  193. bReader := varbin.StubReader(gReader)
  194. var content ProfileContent
  195. content.Name, err = readString(bReader)
  196. if err != nil {
  197. return nil, err
  198. }
  199. err = binary.Read(bReader, binary.BigEndian, &content.Type)
  200. if err != nil {
  201. return nil, err
  202. }
  203. content.Config, err = readString(bReader)
  204. if err != nil {
  205. return nil, err
  206. }
  207. if content.Type != ProfileTypeLocal {
  208. content.RemotePath, err = readString(bReader)
  209. if err != nil {
  210. return nil, err
  211. }
  212. }
  213. if content.Type == ProfileTypeRemote || (version == 0 && content.Type != ProfileTypeLocal) {
  214. err = binary.Read(bReader, binary.BigEndian, &content.AutoUpdate)
  215. if err != nil {
  216. return nil, err
  217. }
  218. if version >= 1 {
  219. err = binary.Read(bReader, binary.BigEndian, &content.AutoUpdateInterval)
  220. if err != nil {
  221. return nil, err
  222. }
  223. }
  224. err = binary.Read(bReader, binary.BigEndian, &content.LastUpdated)
  225. if err != nil {
  226. return nil, err
  227. }
  228. }
  229. return &content, nil
  230. }
  231. func readString(reader io.ByteReader) (string, error) {
  232. length, err := binary.ReadUvarint(reader)
  233. if err != nil {
  234. return "", err
  235. }
  236. buf := make([]byte, length)
  237. for i := range buf {
  238. buf[i], err = reader.ReadByte()
  239. if err != nil {
  240. return "", err
  241. }
  242. }
  243. return string(buf), nil
  244. }
  245. func writeString(buffer *bytes.Buffer, value string) {
  246. varbin.WriteUvarint(buffer, uint64(len(value)))
  247. buffer.WriteString(value)
  248. }
  249. func writeStringBuffered(writer *bufio.Writer, value string) {
  250. varbin.WriteUvarint(writer, uint64(len(value)))
  251. writer.WriteString(value)
  252. }