Add fakeip support

This commit is contained in:
世界
2023-03-25 12:03:23 +08:00
parent a86afa0e5b
commit cbf0099681
29 changed files with 706 additions and 62 deletions

View File

@@ -3,21 +3,28 @@ package clashapi
import (
"net/http"
"github.com/sagernet/sing-box/adapter"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
)
func cacheRouter() http.Handler {
func cacheRouter(router adapter.Router) http.Handler {
r := chi.NewRouter()
r.Post("/fakeip/flush", flushFakeip)
r.Post("/fakeip/flush", flushFakeip(router))
return r
}
func flushFakeip(w http.ResponseWriter, r *http.Request) {
/*if err := cachefile.Cache().FlushFakeip(); err != nil {
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, newError(err.Error()))
return
}*/
render.NoContent(w, r)
func flushFakeip(router adapter.Router) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if cacheFile := router.ClashServer().CacheFile(); cacheFile != nil {
err := cacheFile.FakeIPReset()
if err != nil {
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, newError(err.Error()))
return
}
}
render.NoContent(w, r)
}
}

View File

@@ -0,0 +1,77 @@
package cachefile
import (
"net/netip"
"os"
"github.com/sagernet/sing-box/adapter"
"go.etcd.io/bbolt"
)
var (
bucketFakeIP = []byte("fakeip")
keyMetadata = []byte("metadata")
)
func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata {
var metadata adapter.FakeIPMetadata
err := c.DB.View(func(tx *bbolt.Tx) error {
bucket := tx.Bucket(bucketFakeIP)
if bucket == nil {
return nil
}
metadataBinary := bucket.Get(keyMetadata)
if len(metadataBinary) == 0 {
return os.ErrInvalid
}
return metadata.UnmarshalBinary(metadataBinary)
})
if err != nil {
return nil
}
return &metadata
}
func (c *CacheFile) FakeIPSaveMetadata(metadata *adapter.FakeIPMetadata) error {
return c.DB.Batch(func(tx *bbolt.Tx) error {
bucket, err := tx.CreateBucketIfNotExists(bucketFakeIP)
if err != nil {
return err
}
metadataBinary, err := metadata.MarshalBinary()
if err != nil {
return err
}
return bucket.Put(keyMetadata, metadataBinary)
})
}
func (c *CacheFile) FakeIPStore(address netip.Addr, domain string) error {
return c.DB.Batch(func(tx *bbolt.Tx) error {
bucket, err := tx.CreateBucketIfNotExists(bucketFakeIP)
if err != nil {
return err
}
return bucket.Put(address.AsSlice(), []byte(domain))
})
}
func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) {
var domain string
_ = c.DB.View(func(tx *bbolt.Tx) error {
bucket := tx.Bucket(bucketFakeIP)
if bucket == nil {
return nil
}
domain = string(bucket.Get(address.AsSlice()))
return nil
})
return domain, domain != ""
}
func (c *CacheFile) FakeIPReset() error {
return c.DB.Batch(func(tx *bbolt.Tx) error {
return tx.DeleteBucket(bucketFakeIP)
})
}

View File

@@ -44,6 +44,7 @@ type Server struct {
urlTestHistory *urltest.HistoryStorage
mode string
storeSelected bool
storeFakeIP bool
cacheFilePath string
cacheFile adapter.ClashCacheFile
}
@@ -61,12 +62,13 @@ func NewServer(router adapter.Router, logFactory log.ObservableFactory, options
trafficManager: trafficManager,
urlTestHistory: urltest.NewHistoryStorage(),
mode: strings.ToLower(options.DefaultMode),
storeSelected: options.StoreSelected,
storeFakeIP: options.StoreFakeIP,
}
if server.mode == "" {
server.mode = "rule"
}
if options.StoreSelected {
server.storeSelected = true
if options.StoreSelected || options.StoreFakeIP {
cachePath := os.ExpandEnv(options.CacheFile)
if cachePath == "" {
cachePath = "cache.db"
@@ -99,7 +101,7 @@ func NewServer(router adapter.Router, logFactory log.ObservableFactory, options
r.Mount("/providers/rules", ruleProviderRouter())
r.Mount("/script", scriptRouter())
r.Mount("/profile", profileRouter())
r.Mount("/cache", cacheRouter())
r.Mount("/cache", cacheRouter(router))
r.Mount("/dns", dnsRouter(router))
})
if options.ExternalUI != "" {
@@ -156,6 +158,10 @@ func (s *Server) StoreSelected() bool {
return s.storeSelected
}
func (s *Server) StoreFakeIP() bool {
return s.storeFakeIP
}
func (s *Server) CacheFile() adapter.ClashCacheFile {
return s.cacheFile
}