Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
443bec7
Add MAC and hostname rule items
nekohasekai Mar 3, 2026
9e548cb
Add Android support for MAC and hostname rule items
nekohasekai Mar 4, 2026
d0fd6f6
Add macOS support for MAC and hostname rule items
nekohasekai Mar 6, 2026
f0a057c
documentation: Update descriptions for neighbor rules
nekohasekai Mar 6, 2026
4c6ff22
Refactor ACME support to certificate provider
nekohasekai Mar 23, 2026
914fc9c
Add BBR profile and hop interval randomization for Hysteria2
nekohasekai Mar 30, 2026
17a63d5
platform: Add OOM Report & Crash Report
nekohasekai Apr 2, 2026
01efb67
Also enable certificate store by default on Apple platforms
nekohasekai Apr 7, 2026
6fa641a
Add evaluate DNS rule action and related rule items
nekohasekai Apr 7, 2026
f294557
platform: Fix set local
nekohasekai Apr 7, 2026
b9ac437
Fix deprecated warning double-formatting on localized clients
nekohasekai Apr 7, 2026
3cfbfbb
oom-killer: Free memory on pressure notification and use gradual inte…
nekohasekai Apr 7, 2026
3b5e8c8
tools: Network Quality & STUN
nekohasekai Apr 8, 2026
11b7ffd
platform: Fix darwin signal handler
nekohasekai Apr 9, 2026
7d382fe
tools: Tailscale status
nekohasekai Apr 9, 2026
c5a3e59
Revert "Also enable certificate store by default on Apple platforms"
nekohasekai Apr 9, 2026
1ee527a
Fix rules lock
nekohasekai Apr 9, 2026
775f683
Fix darwin local DNS transport
nekohasekai Apr 10, 2026
972a035
tools: Tailscale status
nekohasekai Apr 10, 2026
825f86a
Un-deprecate `ip_accept_any` DNS rule item
nekohasekai Apr 10, 2026
39dda9f
documentation: Fixes
nekohasekai Apr 10, 2026
0a9d8f9
Add `package_name_regex` route, DNS and headless rule item
nekohasekai Apr 10, 2026
0dc7d6e
platform: Wrap command RPC error returns with E.Cause
nekohasekai Apr 10, 2026
72f8997
Fix lint errors
nekohasekai Apr 10, 2026
0cc5958
Add cloudflared inbound
nekohasekai Apr 10, 2026
9b44e1b
documentation: Fix missing update for `ip_version` and `query_type`
nekohasekai Apr 10, 2026
914a6c5
Fix stun test
nekohasekai Apr 10, 2026
f7cf93e
Fix darwin cgo DNS again
nekohasekai Apr 10, 2026
b207d37
Fix tailscale error
nekohasekai Apr 11, 2026
6f23a96
Add optimistic DNS cache
nekohasekai Apr 11, 2026
04dc9fc
oom-killer: Record report before reset network
nekohasekai Apr 14, 2026
195e129
Refactor: HTTP clients, unified HTTP2/QUIC options, Apple engines
nekohasekai Apr 14, 2026
69f9f02
Standardize hosts path
nekohasekai Apr 15, 2026
227e0ca
Add TLS spoof support
nekohasekai Apr 15, 2026
7fe1f47
Fix legacy rule-set download_detour blocked by empty direct check
nekohasekai Apr 15, 2026
8224f2e
Reject pure-IP rule-set references without match_response
nekohasekai Apr 15, 2026
719a002
Fix use-after-free of pooled value buffers in bbolt Batch writes
nekohasekai Apr 15, 2026
644b9bc
Reject IP literal server name with TLS spoof
nekohasekai Apr 16, 2026
6e59653
Fix macOS tlsspoof
nekohasekai Apr 17, 2026
463d808
Scope HTTP/2 fallback and HTTP/3 broken state per authority
nekohasekai Apr 17, 2026
eedd925
Defer implicit default HTTP client fallback to first use
nekohasekai Apr 17, 2026
596c85a
Strip EDNS padding from upstream DNS responses
nekohasekai Apr 17, 2026
e9bf691
Fix Apple TLS metadata capture
nekohasekai Apr 18, 2026
b656af6
Fix tls-spoof
nekohasekai Apr 17, 2026
6d1803f
Add search domain support for Tailscale DNS
nekohasekai Apr 20, 2026
5f8d846
Log DNS optimistic background refresh outcomes
nekohasekai Apr 21, 2026
a6c4539
Fix Tailscale search domain response name mismatch
nekohasekai Apr 21, 2026
4b9221f
Fix goroutine leak in networkquality tool
nekohasekai Apr 21, 2026
88486da
Add ACME profile support for IP address certificates
nekohasekai Mar 26, 2026
00149d8
Fix ACME HTTP-01 challenge for IPv6 literal addresses
nekohasekai Apr 21, 2026
881736a
platform: Improve oom-killer
nekohasekai Apr 21, 2026
58a318f
Fix darwin cgo DNS again
nekohasekai Apr 22, 2026
77142b6
Fix stderr deprecated manager
nekohasekai Apr 23, 2026
770a0c7
Improve UDP batch support
nekohasekai Apr 24, 2026
d7f4cef
Add Windows TLS engine
nekohasekai Apr 24, 2026
a31244b
tun: Add compatibility with docker bridge
nekohasekai Apr 24, 2026
b268fe0
Preserve comments between formatting
nekohasekai Apr 28, 2026
73fc988
Improve oom-killer
nekohasekai Apr 28, 2026
5d0c132
tun: Add read waiter support for gVisor conn
nekohasekai Apr 28, 2026
19f696d
ssh: Add cipher, MAC, and key exchange configuration
nekohasekai Apr 28, 2026
7b258f2
dns: Add timeout configuration
nekohasekai Apr 28, 2026
3076764
Fix tailscale start dependencies
nekohasekai Apr 28, 2026
d701464
dns: Add neighbor-based hostname resolution to local server
nekohasekai Apr 29, 2026
d02a055
dns: Add preferred_by rule item
nekohasekai Apr 29, 2026
93d3869
dns: Add mDNS server
nekohasekai Apr 30, 2026
ac900b1
Allow customizing TUN DNS mode and hijack interface DNS by default
nekohasekai May 2, 2026
ef06e4c
Add more spoof method
macronut Apr 29, 2026
895bc40
Fix reset network
nekohasekai May 5, 2026
0ce4cbd
Add hysteria2 realm service and support
nekohasekai May 10, 2026
6275582
Update hysteria2 realm
nekohasekai May 11, 2026
5f2bedf
Fix TLS server close
nekohasekai May 12, 2026
81dd85f
realm: Add stun retry and lazy server start
nekohasekai May 12, 2026
588c8ba
Fix hysteria2 realm server
nekohasekai May 12, 2026
21e27a2
Fix lint errors
nekohasekai May 14, 2026
6b07a22
Bump version
nekohasekai Mar 7, 2026
646c7ac
dns: Fix DHCP reset
nekohasekai May 17, 2026
4138054
Rebase wireguard-go to official
nekohasekai May 17, 2026
35cf647
Fix shadowtls handshake
nekohasekai May 17, 2026
27f5835
cronet: Fix vendor package
nekohasekai May 18, 2026
131326f
tun: Fix unprivileged ping conn leak
nekohasekai May 19, 2026
db5fcc6
tun: Fix IPv6 UDP packet leak in system stack
nekohasekai May 19, 2026
0ae672d
oom-killer: Remove log "OOM draft discarded"
nekohasekai May 19, 2026
0a921bb
tun: Handle existing wintun adapter on restart
nekohasekai May 19, 2026
279f815
route: Refetch rule-set when cache restore fails
nekohasekai May 19, 2026
cf06742
process: Fix panic when package manager is unavailable on Android
nekohasekai May 19, 2026
8785b39
tailscale: Revert dialer deprecation and remove control_http_client
nekohasekai May 20, 2026
9f3206d
tailscale: Fix handle peer DNS query
nekohasekai May 20, 2026
bb7405e
gvisor: Fix dialing to self addresses
nekohasekai May 20, 2026
ae9a2a0
realm: Open separate v4 and v6 packet conns on client
nekohasekai May 20, 2026
b5ac202
Update Go to 1.25.10
nekohasekai May 20, 2026
e7891c9
Fix tailscale
nekohasekai May 21, 2026
f3458a9
tailscale: Add runtime exit node API
nekohasekai May 21, 2026
b37b6b1
tailscale: Expose more peer info fields
nekohasekai May 21, 2026
9bc35c4
Fix tailscale dns
nekohasekai May 21, 2026
33dfec2
sing: Fix comment loop
nekohasekai May 22, 2026
812a8fd
Bump version
nekohasekai May 20, 2026
c29c5db
experimental/clashapi: emit "user" in TrackerMetadata.MarshalJSON
PavelLizunov May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/CRONET_GO_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2faf34666c2cc8234f10f2ab6d4c4d6104d34ae2
b3eec8134aec1387d850e0671dd8531e2e6140b0
2 changes: 1 addition & 1 deletion .github/setup_go_for_macos1013.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -euo pipefail

VERSION="1.25.9"
VERSION="1.25.10"
PATCH_COMMITS=(
"afe69d3cec1c6dcf0f1797b20546795730850070"
"1ed289b0cf87dc5aae9c6fe1aa5f200a83412938"
Expand Down
2 changes: 1 addition & 1 deletion .github/setup_go_for_windows7.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -euo pipefail

VERSION="1.25.9"
VERSION="1.25.10"
PATCH_COMMITS=(
"466f6c7a29bc098b0d4c987b803c779222894a11"
"1bdabae205052afe1dadb2ad6f1ba612cdbc532a"
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
go-version: ~1.25.10
- name: Check input version
if: github.event_name == 'workflow_dispatch'
run: |-
Expand Down Expand Up @@ -124,7 +124,7 @@ jobs:
if: ${{ ! matrix.legacy_win7 }}
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
go-version: ~1.25.10
- name: Cache Go for Windows 7
if: matrix.legacy_win7
id: cache-go-for-windows7
Expand Down Expand Up @@ -641,7 +641,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
go-version: ~1.25.10
- name: Setup Android NDK
id: setup-ndk
uses: nttld/setup-ndk@v1
Expand Down Expand Up @@ -731,7 +731,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
go-version: ~1.25.10
- name: Setup Android NDK
id: setup-ndk
uses: nttld/setup-ndk@v1
Expand Down Expand Up @@ -830,7 +830,7 @@ jobs:
if: matrix.if
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
go-version: ~1.25.10
- name: Set tag
if: matrix.if
run: |-
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
go-version: ~1.25.10
- name: Clone cronet-go
if: matrix.naive
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
go-version: ~1.25.10
- name: Check input version
if: github.event_name == 'workflow_dispatch'
run: |-
Expand Down Expand Up @@ -72,7 +72,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ~1.25.9
go-version: ~1.25.10
- name: Clone cronet-go
if: matrix.naive
run: |
Expand Down
55 changes: 55 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Test

on:
push:
branches:
- stable
- testing
- unstable
paths-ignore:
- '**.md'
- '.github/**'
- '!.github/workflows/test.yml'
pull_request:
branches:
- stable
- testing
- unstable

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}-${{ inputs.build }}
cancel-in-progress: true

jobs:
test:
name: Test
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- windows-latest
- macos-latest
go:
- ~1.24
- ~1.25
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
- name: Set build tags and ldflags
shell: bash
run: |
echo "BUILD_TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)" >> "$GITHUB_ENV"
echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "$GITHUB_ENV"
- name: Test (unix)
if: matrix.os != 'windows-latest'
run: go test -v -exec sudo -tags "$BUILD_TAGS" -ldflags "$LDFLAGS_SHARED" ./...
- name: Test (windows)
if: matrix.os == 'windows-latest'
shell: bash
run: go test -v -tags "$BUILD_TAGS" -ldflags "$LDFLAGS_SHARED" ./...
1 change: 0 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ linters:
default: none
enable:
- ineffassign
- paralleltest
- staticcheck
- unused
- modernize
Expand Down
1 change: 1 addition & 0 deletions adapter/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
type CertificateStore interface {
LifecycleService
Pool() *x509.CertPool
ExclusiveAnchors() bool
}

func RootPoolFromContext(ctx context.Context) *x509.CertPool {
Expand Down
21 changes: 21 additions & 0 deletions adapter/certificate/adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package certificate

type Adapter struct {
providerType string
providerTag string
}

func NewAdapter(providerType string, providerTag string) Adapter {
return Adapter{
providerType: providerType,
providerTag: providerTag,
}
}

func (a *Adapter) Type() string {
return a.providerType
}

func (a *Adapter) Tag() string {
return a.providerTag
}
158 changes: 158 additions & 0 deletions adapter/certificate/manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package certificate

import (
"context"
"os"
"sync"
"time"

"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
)

var _ adapter.CertificateProviderManager = (*Manager)(nil)

type Manager struct {
logger log.ContextLogger
registry adapter.CertificateProviderRegistry
access sync.Mutex
started bool
stage adapter.StartStage
providers []adapter.CertificateProviderService
providerByTag map[string]adapter.CertificateProviderService
}

func NewManager(logger log.ContextLogger, registry adapter.CertificateProviderRegistry) *Manager {
return &Manager{
logger: logger,
registry: registry,
providerByTag: make(map[string]adapter.CertificateProviderService),
}
}

func (m *Manager) Start(stage adapter.StartStage) error {
m.access.Lock()
if m.started && m.stage >= stage {
panic("already started")
}
m.started = true
m.stage = stage
providers := m.providers
m.access.Unlock()
for _, provider := range providers {
name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err := adapter.LegacyStart(provider, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return nil
}

func (m *Manager) Close() error {
m.access.Lock()
defer m.access.Unlock()
if !m.started {
return nil
}
m.started = false
providers := m.providers
m.providers = nil
monitor := taskmonitor.New(m.logger, C.StopTimeout)
var err error
for _, provider := range providers {
name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
m.logger.Trace("close ", name)
startTime := time.Now()
monitor.Start("close ", name)
err = E.Append(err, provider.Close(), func(err error) error {
return E.Cause(err, "close ", name)
})
monitor.Finish()
m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
return err
}

func (m *Manager) CertificateProviders() []adapter.CertificateProviderService {
m.access.Lock()
defer m.access.Unlock()
return m.providers
}

func (m *Manager) Get(tag string) (adapter.CertificateProviderService, bool) {
m.access.Lock()
provider, found := m.providerByTag[tag]
m.access.Unlock()
return provider, found
}

func (m *Manager) Remove(tag string) error {
m.access.Lock()
provider, found := m.providerByTag[tag]
if !found {
m.access.Unlock()
return os.ErrInvalid
}
delete(m.providerByTag, tag)
index := common.Index(m.providers, func(it adapter.CertificateProviderService) bool {
return it == provider
})
if index == -1 {
panic("invalid certificate provider index")
}
m.providers = append(m.providers[:index], m.providers[index+1:]...)
started := m.started
m.access.Unlock()
if started {
return provider.Close()
}
return nil
}

func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) error {
provider, err := m.registry.Create(ctx, logger, tag, providerType, options)
if err != nil {
return err
}
m.access.Lock()
defer m.access.Unlock()
if m.started {
name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
for _, stage := range adapter.ListStartStages {
m.logger.Trace(stage, " ", name)
startTime := time.Now()
err = adapter.LegacyStart(provider, stage)
if err != nil {
return E.Cause(err, stage, " ", name)
}
m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
}
if existsProvider, loaded := m.providerByTag[tag]; loaded {
if m.started {
err = existsProvider.Close()
if err != nil {
return E.Cause(err, "close certificate-provider/", existsProvider.Type(), "[", existsProvider.Tag(), "]")
}
}
existsIndex := common.Index(m.providers, func(it adapter.CertificateProviderService) bool {
return it == existsProvider
})
if existsIndex == -1 {
panic("invalid certificate provider index")
}
m.providers = append(m.providers[:existsIndex], m.providers[existsIndex+1:]...)
}
m.providers = append(m.providers, provider)
m.providerByTag[tag] = provider
return nil
}
Loading