experimental.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package adapter
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/binary"
  6. "io"
  7. "time"
  8. "github.com/sagernet/sing/common/observable"
  9. "github.com/sagernet/sing/common/varbin"
  10. )
  11. type ClashServer interface {
  12. LifecycleService
  13. ConnectionTracker
  14. Mode() string
  15. ModeList() []string
  16. SetModeUpdateHook(hook *observable.Subscriber[struct{}])
  17. HistoryStorage() URLTestHistoryStorage
  18. }
  19. type URLTestHistory struct {
  20. Time time.Time `json:"time"`
  21. Delay uint16 `json:"delay"`
  22. }
  23. type URLTestHistoryStorage interface {
  24. SetHook(hook *observable.Subscriber[struct{}])
  25. LoadURLTestHistory(tag string) *URLTestHistory
  26. DeleteURLTestHistory(tag string)
  27. StoreURLTestHistory(tag string, history *URLTestHistory)
  28. Close() error
  29. }
  30. type V2RayServer interface {
  31. LifecycleService
  32. StatsService() ConnectionTracker
  33. }
  34. type CacheFile interface {
  35. LifecycleService
  36. StoreFakeIP() bool
  37. FakeIPStorage
  38. StoreRDRC() bool
  39. RDRCStore
  40. StoreDNS() bool
  41. DNSCacheStore
  42. SetDisableExpire(disableExpire bool)
  43. SetOptimisticTimeout(timeout time.Duration)
  44. LoadMode() string
  45. StoreMode(mode string) error
  46. LoadSelected(group string) string
  47. StoreSelected(group string, selected string) error
  48. LoadGroupExpand(group string) (isExpand bool, loaded bool)
  49. StoreGroupExpand(group string, expand bool) error
  50. LoadRuleSet(tag string) *SavedBinary
  51. SaveRuleSet(tag string, set *SavedBinary) error
  52. }
  53. type SavedBinary struct {
  54. Content []byte
  55. LastUpdated time.Time
  56. LastEtag string
  57. }
  58. func (s *SavedBinary) MarshalBinary() ([]byte, error) {
  59. var buffer bytes.Buffer
  60. err := binary.Write(&buffer, binary.BigEndian, uint8(1))
  61. if err != nil {
  62. return nil, err
  63. }
  64. _, err = varbin.WriteUvarint(&buffer, uint64(len(s.Content)))
  65. if err != nil {
  66. return nil, err
  67. }
  68. _, err = buffer.Write(s.Content)
  69. if err != nil {
  70. return nil, err
  71. }
  72. err = binary.Write(&buffer, binary.BigEndian, s.LastUpdated.Unix())
  73. if err != nil {
  74. return nil, err
  75. }
  76. _, err = varbin.WriteUvarint(&buffer, uint64(len(s.LastEtag)))
  77. if err != nil {
  78. return nil, err
  79. }
  80. _, err = buffer.WriteString(s.LastEtag)
  81. if err != nil {
  82. return nil, err
  83. }
  84. return buffer.Bytes(), nil
  85. }
  86. func (s *SavedBinary) UnmarshalBinary(data []byte) error {
  87. reader := bytes.NewReader(data)
  88. var version uint8
  89. err := binary.Read(reader, binary.BigEndian, &version)
  90. if err != nil {
  91. return err
  92. }
  93. contentLength, err := binary.ReadUvarint(reader)
  94. if err != nil {
  95. return err
  96. }
  97. s.Content = make([]byte, contentLength)
  98. _, err = io.ReadFull(reader, s.Content)
  99. if err != nil {
  100. return err
  101. }
  102. var lastUpdated int64
  103. err = binary.Read(reader, binary.BigEndian, &lastUpdated)
  104. if err != nil {
  105. return err
  106. }
  107. s.LastUpdated = time.Unix(lastUpdated, 0)
  108. etagLength, err := binary.ReadUvarint(reader)
  109. if err != nil {
  110. return err
  111. }
  112. etagBytes := make([]byte, etagLength)
  113. _, err = io.ReadFull(reader, etagBytes)
  114. if err != nil {
  115. return err
  116. }
  117. s.LastEtag = string(etagBytes)
  118. return nil
  119. }
  120. type OutboundGroup interface {
  121. Outbound
  122. Now() string
  123. All() []string
  124. }
  125. type URLTestGroup interface {
  126. OutboundGroup
  127. URLTest(ctx context.Context) (map[string]uint16, error)
  128. }
  129. func OutboundTag(detour Outbound) string {
  130. if group, isGroup := detour.(OutboundGroup); isGroup {
  131. return group.Now()
  132. }
  133. return detour.Tag()
  134. }