Skip to content

Add ClashAPI (Rule Provider) For RuleSet #1266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 25 commits into
base: dev-next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ad93b45
Migrate to independent cache file
nekohasekai Nov 28, 2023
340e74e
Allow nested logical rules
nekohasekai Nov 28, 2023
411f02e
Update buffer usage
nekohasekai Nov 29, 2023
bb70e82
Add rule-set
nekohasekai Dec 1, 2023
3a9b787
Independent `source_ip_is_private` and `ip_is_private` rules
nekohasekai Dec 1, 2023
3041f34
Update documentation
nekohasekai Dec 1, 2023
80cc0cd
Migrate contentjson and badjson to library &
nekohasekai Dec 1, 2023
d1ad342
Skip internal fake-ip queries
nekohasekai Dec 1, 2023
fc9804b
Add `idle_timeout` for URLTest outbound
nekohasekai Dec 3, 2023
f998cce
Update documentation
nekohasekai Dec 3, 2023
abd4d8b
Avoid opening log output before start &
nekohasekai Dec 4, 2023
bc2d73b
Remove comparable limit for Listable
nekohasekai Dec 4, 2023
2f4f4e1
Make type check strict
nekohasekai Dec 5, 2023
a99c310
Improve read wait interface &
nekohasekai Dec 15, 2023
b0cd7af
Remove unnecessary context wrappers
nekohasekai Dec 16, 2023
2b518d3
Update cloudflare-tls to go1.21.5
nekohasekai Dec 8, 2023
9dedf8b
Update gomobile and add tag
nekohasekai Dec 8, 2023
0732b63
Update tfo-go
nekohasekai Dec 9, 2023
5052e86
Update uTLS to 1.5.4
nekohasekai Dec 9, 2023
7740293
Improve configuration merge
nekohasekai Dec 10, 2023
6d4f54d
Refactor inbound/outbound options struct
nekohasekai Dec 11, 2023
285278b
Make generated files have `SUDO_USER`'s permissions if possible.
nekohasekai Dec 17, 2023
7340793
documentation: Fix link format
nekohasekai Dec 14, 2023
bdfe6ec
documentation: Bump version
nekohasekai Dec 7, 2023
ac28333
Add RuleSet ClashAPI (Rule Provider)
0xffffharry Dec 20, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/.idea/
/vendor/
/*.json
/*.srs
/*.db
/site/
/bin/
Expand Down
9 changes: 4 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
NAME = sing-box
COMMIT = $(shell git rev-parse --short HEAD)
TAGS_GO118 = with_gvisor,with_dhcp,with_wireguard,with_utls,with_reality_server,with_clash_api
TAGS_GO120 = with_quic,with_ech
TAGS_GO118 = with_gvisor,with_dhcp,with_wireguard,with_reality_server,with_clash_api
TAGS_GO120 = with_quic,with_ech,with_utls
TAGS ?= $(TAGS_GO118),$(TAGS_GO120)
TAGS_TEST ?= with_gvisor,with_quic,with_wireguard,with_grpc,with_ech,with_utls,with_reality_server

Expand Down Expand Up @@ -178,9 +178,8 @@ lib:
go run ./cmd/internal/build_libbox -target ios

lib_install:
go get -v -d
go install -v github.com/sagernet/gomobile/cmd/[email protected]
go install -v github.com/sagernet/gomobile/cmd/[email protected]
go install -v github.com/sagernet/gomobile/cmd/[email protected]
go install -v github.com/sagernet/gomobile/cmd/[email protected]

docs:
mkdocs serve
Expand Down
76 changes: 71 additions & 5 deletions adapter/experimental.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,100 @@
package adapter

import (
"bytes"
"context"
"encoding/binary"
"io"
"net"
"time"

"github.com/sagernet/sing-box/common/urltest"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/rw"
)

type ClashServer interface {
Service
PreStarter
Mode() string
ModeList() []string
StoreSelected() bool
StoreFakeIP() bool
CacheFile() ClashCacheFile
HistoryStorage() *urltest.HistoryStorage
RoutedConnection(ctx context.Context, conn net.Conn, metadata InboundContext, matchedRule Rule) (net.Conn, Tracker)
RoutedPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext, matchedRule Rule) (N.PacketConn, Tracker)
}

type ClashCacheFile interface {
type CacheFile interface {
Service
PreStarter

StoreFakeIP() bool
FakeIPStorage

LoadMode() string
StoreMode(mode string) error
LoadSelected(group string) string
StoreSelected(group string, selected string) error
LoadGroupExpand(group string) (isExpand bool, loaded bool)
StoreGroupExpand(group string, expand bool) error
FakeIPStorage
LoadRuleSet(tag string) *SavedRuleSet
SaveRuleSet(tag string, set *SavedRuleSet) error
}

type SavedRuleSet struct {
Content []byte
LastUpdated time.Time
LastEtag string
}

func (s *SavedRuleSet) MarshalBinary() ([]byte, error) {
var buffer bytes.Buffer
err := binary.Write(&buffer, binary.BigEndian, uint8(1))
if err != nil {
return nil, err
}
err = rw.WriteUVariant(&buffer, uint64(len(s.Content)))
if err != nil {
return nil, err
}
buffer.Write(s.Content)
err = binary.Write(&buffer, binary.BigEndian, s.LastUpdated.Unix())
if err != nil {
return nil, err
}
err = rw.WriteVString(&buffer, s.LastEtag)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}

func (s *SavedRuleSet) UnmarshalBinary(data []byte) error {
reader := bytes.NewReader(data)
var version uint8
err := binary.Read(reader, binary.BigEndian, &version)
if err != nil {
return err
}
contentLen, err := rw.ReadUVariant(reader)
if err != nil {
return err
}
s.Content = make([]byte, contentLen)
_, err = io.ReadFull(reader, s.Content)
if err != nil {
return err
}
var lastUpdated int64
err = binary.Read(reader, binary.BigEndian, &lastUpdated)
if err != nil {
return err
}
s.LastUpdated = time.Unix(lastUpdated, 0)
s.LastEtag, err = rw.ReadVString(reader)
if err != nil {
return err
}
return nil
}

type Tracker interface {
Expand Down
17 changes: 15 additions & 2 deletions adapter/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,24 @@ type InboundContext struct {
SourceGeoIPCode string
GeoIPCode string
ProcessInfo *process.Info
QueryType uint16
FakeIP bool

// dns cache
// rule cache

QueryType uint16
IPCIDRMatchSource bool
SourceAddressMatch bool
SourcePortMatch bool
DestinationAddressMatch bool
DestinationPortMatch bool
}

func (c *InboundContext) ResetRuleCache() {
c.IPCIDRMatchSource = false
c.SourceAddressMatch = false
c.SourcePortMatch = false
c.DestinationAddressMatch = false
c.DestinationPortMatch = false
}

type inboundContextKey struct{}
Expand Down
42 changes: 38 additions & 4 deletions adapter/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,28 @@ package adapter

import (
"context"
"net/http"
"net/netip"
"time"

"github.com/sagernet/sing-box/common/geoip"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing-tun"
dns "github.com/sagernet/sing-dns"
tun "github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/control"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/service"

mdns "github.com/miekg/dns"
)

type Router interface {
Service
PreStarter
PostStarter

Outbounds() []Outbound
Outbound(tag string) (Outbound, bool)
DefaultOutbound(network string) Outbound
DefaultOutbound(network string) (Outbound, error)

FakeIPStore() FakeIPStore

Expand All @@ -28,6 +32,9 @@ type Router interface {
GeoIPReader() *geoip.Reader
LoadGeosite(code string) (Rule, error)

RuleSet(tag string) (RuleSet, bool)
RuleSets() []RuleSet

Exchange(ctx context.Context, message *mdns.Msg) (*mdns.Msg, error)
Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error)
LookupDefault(ctx context.Context, domain string) ([]netip.Addr, error)
Expand Down Expand Up @@ -62,11 +69,15 @@ func RouterFromContext(ctx context.Context) Router {
return service.FromContext[Router](ctx)
}

type HeadlessRule interface {
Match(metadata *InboundContext) bool
}

type Rule interface {
HeadlessRule
Service
Type() string
UpdateGeosite() error
Match(metadata *InboundContext) bool
Outbound() string
String() string
}
Expand All @@ -77,6 +88,29 @@ type DNSRule interface {
RewriteTTL() *uint32
}

type RuleSet interface {
Tag() string
Type() string
StartContext(ctx context.Context, startContext RuleSetStartContext) error
PostStart() error
Metadata() RuleSetMetadata
Close() error
HeadlessRule
}

type RuleSetMetadata struct {
ContainsProcessRule bool
ContainsWIFIRule bool
RuleNum int
LastUpdated time.Time
Format string
}

type RuleSetStartContext interface {
HTTPClient(detour string, dialer N.Dialer) *http.Client
Close()
}

type InterfaceUpdateListener interface {
InterfaceUpdated()
}
Expand Down
Loading