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) }) }